From b0413aa7d43cd19908360ebaff1cbf250a79c46b Mon Sep 17 00:00:00 2001
From: Ted Nathan Husted
Date: Tue, 10 Oct 2006 21:40:12 +0000
Subject: [PATCH] Tag r462587 as Struts 2.0.1 (again)
git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/tags/STRUTS_2_0_1@462588 13f79535-47bb-0310-9956-ffa450edef68
---
trunk/all/pom.xml | 125 +
trunk/api/pom.xml | 47 +
.../main/java/org/apache/struts2/Action.java | 45 +
.../java/org/apache/struts2/MessageAware.java | 41 +
.../java/org/apache/struts2/Messages.java | 196 +
.../java/org/apache/struts2/ResultNames.java | 36 +
.../java/org/apache/struts2/Validatable.java | 17 +
.../struts2/servlet/ParameterAware.java | 18 +
.../struts2/servlet/ServletRequestAware.java | 18 +
.../struts2/servlet/ServletResponseAware.java | 18 +
.../org/apache/struts2/spi/ActionContext.java | 59 +
.../org/apache/struts2/spi/Interceptor.java | 16 +
.../apache/struts2/spi/RequestContext.java | 101 +
.../struts2/spi/RequestContextAware.java | 19 +
.../java/org/apache/struts2/spi/Result.java | 18 +
.../org/apache/struts2/spi/ValueStack.java | 93 +
trunk/apps/blank/README.txt | 10 +
trunk/apps/blank/pom.xml | 46 +
.../src/main/java/example/ExampleSupport.java | 9 +
.../src/main/java/example/HelloWorld.java | 40 +
.../blank/src/main/java/example/Login.java | 38 +
.../blank/src/main/java/example/build.bat | 3 +
.../apps/blank/src/main/resources/example.xml | 24 +
.../resources/example/Login-validation.xml | 16 +
.../main/resources/example/package.properties | 5 +
.../resources/example/package_es.properties | 5 +
.../src/main/resources/struts.properties | 2 +
.../apps/blank/src/main/resources/struts.xml | 11 +
.../webapp/WEB-INF/applicationContext.xml | 6 +
.../blank/src/main/webapp/WEB-INF/web.xml | 34 +
.../src/main/webapp/example/HelloWorld.jsp | 28 +
.../blank/src/main/webapp/example/Login.jsp | 15 +
.../blank/src/main/webapp/example/Menu.jsp | 3 +
.../blank/src/main/webapp/example/Missing.jsp | 11 +
.../src/main/webapp/example/Register.jsp | 3 +
.../blank/src/main/webapp/example/Welcome.jsp | 18 +
trunk/apps/blank/src/main/webapp/index.html | 10 +
.../src/test/java/example/ConfigTest.java | 76 +
.../src/test/java/example/HelloWorldTest.java | 16 +
.../src/test/java/example/LoginTest.java | 36 +
trunk/apps/mailreader/README.txt | 18 +
trunk/apps/mailreader/pom.xml | 58 +
.../src/main/java/alternate.properties | 3 +
.../src/main/java/alternate_ja.properties | 1 +
.../src/main/java/applicationContext.xml | 6 +
.../src/main/java/mailreader-default.xml | 47 +
.../src/main/java/mailreader-support.xml | 63 +
.../java/mailreader2/ApplicationListener.java | 231 +
.../AuthenticationInterceptor.java | 31 +
.../src/main/java/mailreader2/Constants.java | 125 +
.../src/main/java/mailreader2/Login.java | 45 +
.../java/mailreader2/Logon-validation.xml | 14 +
.../src/main/java/mailreader2/Logout.java | 32 +
.../java/mailreader2/MailreaderSupport.java | 559 +
.../mailreader2/MailreaderSupport.properties | 93 +
.../MailreaderSupport_ja.properties | 89 +
.../MailreaderSupport_ru.properties | 89 +
...istration-Registration!save-validation.xml | 28 +
.../mailreader2/Registration-validation.xml | 32 +
.../main/java/mailreader2/Registration.java | 101 +
...scription-Subscription!save-validation.xml | 23 +
.../mailreader2/Subscription-validation.xml | 11 +
.../main/java/mailreader2/Subscription.java | 124 +
.../src/main/java/mailreader2/Welcome.java | 28 +
.../src/main/java/struts.properties | 4 +
.../apps/mailreader/src/main/java/struts.xml | 12 +
.../src/main/webapp/ChangePassword.jsp | 25 +
.../apps/mailreader/src/main/webapp/Error.jsp | 40 +
.../mailreader/src/main/webapp/Footer.jsp | 6 +
.../apps/mailreader/src/main/webapp/Login.jsp | 30 +
.../src/main/webapp/META-INF/context.xml | 3 +
.../mailreader/src/main/webapp/MainMenu.jsp | 25 +
.../src/main/webapp/Registration.jsp | 126 +
.../src/main/webapp/Subscription.jsp | 68 +
.../src/main/webapp/WEB-INF/database.xml | 13 +
.../src/main/webapp/WEB-INF/web.xml | 41 +
.../mailreader/src/main/webapp/Welcome.jsp | 56 +
.../src/main/webapp/css/mailreader.css | 46 +
.../mailreader/src/main/webapp/index.html | 10 +
.../src/main/webapp/struts-power.gif | Bin 0 -> 1798 bytes
.../apps/mailreader/src/main/webapp/tour.html | 2479 ++++
trunk/apps/pom.xml | 216 +
trunk/apps/portlet/README.txt | 17 +
trunk/apps/portlet/pom.xml | 44 +
trunk/apps/portlet/src/main/etc/exo/web.xml | 63 +
.../main/etc/gridsphere/README-gridsphere.txt | 2 +
.../etc/gridsphere/gridsphere-portlet.xml | 24 +
.../portlet/src/main/etc/gridsphere/group.xml | 10 +
.../src/main/etc/gridsphere/layout.xml | 19 +
.../src/main/etc/gridsphere/struts-portlet | 0
.../portlet/src/main/etc/gridsphere/web.xml | 63 +
.../src/main/etc/jbossportal2.0/jboss-app.xml | 3 +
.../main/etc/jbossportal2.0/jboss-portlet.xml | 12 +
.../src/main/etc/jbossportal2.0/jboss-web.xml | 3 +
.../etc/jbossportal2.0/portlet-instances.xml | 11 +
.../jbossportal2.0/struts-portlet-pages.xml | 18 +
.../src/main/etc/jbossportal2.2/jboss-app.xml | 3 +
.../main/etc/jbossportal2.2/jboss-portlet.xml | 12 +
.../src/main/etc/jbossportal2.2/jboss-web.xml | 3 +
.../jbossportal2.2/struts-portlet-object.xml | 25 +
.../main/etc/jetspeed2/README-jetspeed2.txt | 1 +
.../main/etc/jetspeed2/struts-portlet.psml | 20 +
.../portlet/src/main/etc/liferay3.6.1/web.xml | 75 +
.../portlet/example/ExampleAction.java | 36 +
.../struts2/portlet/example/FormExample.java | 44 +
.../example/FormExampleWithValidation.java | 44 +
.../portlet/example/FormResultAction.java | 46 +
.../portlet/example/FormTestAction.java | 33 +
.../portlet/example/SavePrefsAction.java | 59 +
.../portlet/example/spring/SpringAction.java | 55 +
.../portlet/example/spring/ThingManager.java | 35 +
.../main/resources/commons-logging.properties | 2 +
.../apps/portlet/src/main/resources/log4j.xml | 15 +
...le-processValidationExample-validation.xml | 13 +
.../src/main/resources/struts.properties | 1 +
.../template/xhtml/components/checkbox.vm | 12 +
.../template/xhtml/components/datefield.vm | 8 +
.../template/xhtml/components/mytextfield.vm | 15 +
.../portlet/src/main/resources/validators.xml | 13 +
.../apps/portlet/src/main/resources/xwork.xml | 161 +
.../webapp/WEB-INF/applicationContext.xml | 18 +
.../portlet/src/main/webapp/WEB-INF/dwr.xml | 21 +
.../main/webapp/WEB-INF/edit/defaultEdit.jsp | 5 +
.../main/webapp/WEB-INF/edit/formExample.jsp | 5 +
.../webapp/WEB-INF/edit/formExampleInput.jsp | 8 +
.../src/main/webapp/WEB-INF/edit/index.jsp | 11 +
.../webapp/WEB-INF/edit/namespaceTest.jsp | 4 +
.../main/webapp/WEB-INF/edit/prefsForm.jsp | 6 +
.../main/webapp/WEB-INF/edit/prefsSaved.jsp | 5 +
.../src/main/webapp/WEB-INF/edit/test.jsp | 4 +
.../main/webapp/WEB-INF/help/defaultHelp.jsp | 1 +
.../src/main/webapp/WEB-INF/help/index.jsp | 1 +
.../src/main/webapp/WEB-INF/portlet.xml | 118 +
.../src/main/webapp/WEB-INF/readme.txt | 10 +
.../src/main/webapp/WEB-INF/view/ajax.jsp | 1 +
.../src/main/webapp/WEB-INF/view/ajaxData.jsp | 1 +
.../main/webapp/WEB-INF/view/ajaxExample.jsp | 48 +
.../main/webapp/WEB-INF/view/formExample.jsp | 5 +
.../webapp/WEB-INF/view/formExampleInput.jsp | 8 +
.../view/formExampleInputValidation.jsp | 8 +
.../webapp/WEB-INF/view/freeMarkerExample.ftl | 3 +
.../WEB-INF/view/freeMarkerExampleInput.ftl | 5 +
.../main/webapp/WEB-INF/view/helloWorld.vm | 1 +
.../src/main/webapp/WEB-INF/view/index.jsp | 15 +
.../webapp/WEB-INF/view/notImplemented.jsp | 1 +
.../webapp/WEB-INF/view/springExample.jsp | 16 +
.../main/webapp/WEB-INF/view/tokenExample.jsp | 5 +
.../webapp/WEB-INF/view/tokenExampleInput.jsp | 20 +
.../portlet/src/main/webapp/WEB-INF/web.xml | 49 +
.../portlet/src/main/webapp/styles/styles.css | 7 +
trunk/apps/showcase/README.txt | 10 +
trunk/apps/showcase/pom.xml | 161 +
trunk/apps/showcase/quickstart.xml | 66 +
.../apache/struts2/showcase/DateAction.java | 104 +
.../struts2/showcase/DateAction.properties | 1 +
.../showcase/DynamicTreeSelectAction.java | 35 +
.../org/apache/struts2/showcase/Guess.java | 68 +
.../LotsOfOptiontransferselectAction.java | 223 +
...-lotsOfRichtexteditorSubmit-validation.xml | 30 +
.../showcase/LotsOfRichtexteditorAction.java | 75 +
.../showcase/ShowDynamicTreeAction.java | 17 +
.../UITagExample-conversion.properties | 1 +
.../apache/struts2/showcase/UITagExample.java | 314 +
.../showcase/action/AbstractCRUDAction.java | 93 +
.../EmployeeAction-conversion.properties | 1 +
.../action/EmployeeAction-validation.xml | 21 +
.../showcase/action/EmployeeAction.java | 122 +
.../showcase/action/EmployeeAction.properties | 9 +
.../action/EmployeeAction_de.properties | 9 +
.../action/SkillAction-validation.xml | 11 +
.../struts2/showcase/action/SkillAction.java | 85 +
.../showcase/action/SkillAction.properties | 6 +
.../showcase/action/SkillAction_de.properties | 6 +
.../showcase/actionchaining/ActionChain1.java | 42 +
.../showcase/actionchaining/ActionChain2.java | 55 +
.../showcase/actionchaining/ActionChain3.java | 65 +
.../struts2/showcase/ajax/AjaxTestAction.java | 49 +
.../ajax/Example4ShowPanelAction.java | 72 +
.../struts2/showcase/ajax/Example5Action.java | 23 +
.../struts2/showcase/ajax/tree/Category.java | 101 +
.../showcase/ajax/tree/GetCategory.java | 46 +
.../struts2/showcase/ajax/tree/Toggle.java | 32 +
.../showcase/application/MemoryStorage.java | 140 +
.../struts2/showcase/application/Storage.java | 47 +
.../application/TestDataProvider.java | 115 +
.../chat/ChatAuthenticationInterceptor.java | 57 +
.../struts2/showcase/chat/ChatException.java | 33 +
.../showcase/chat/ChatInterceptor.java | 58 +
.../showcase/chat/ChatLoginAction.java | 65 +
.../showcase/chat/ChatLogoutAction.java | 55 +
.../struts2/showcase/chat/ChatMessage.java | 46 +
.../struts2/showcase/chat/ChatService.java | 34 +
.../showcase/chat/ChatServiceImpl.java | 112 +
.../showcase/chat/ChatSessionListener.java | 50 +
.../struts2/showcase/chat/Constants.java | 22 +
.../struts2/showcase/chat/CrudRoomAction.java | 61 +
.../struts2/showcase/chat/DateConverter.java | 56 +
.../showcase/chat/EnterRoomAction.java | 59 +
.../struts2/showcase/chat/ExitRoomAction.java | 55 +
.../chat/MessagesAvailableInRoomAction.java | 56 +
.../apache/struts2/showcase/chat/Room.java | 98 +
.../showcase/chat/RoomsAvailableAction.java | 45 +
.../chat/SendMessageToRoomAction.java | 67 +
.../apache/struts2/showcase/chat/User.java | 45 +
.../showcase/chat/UsersAvailableAction.java | 46 +
.../chat/UsersAvailableInRoomAction.java | 58 +
.../struts2/showcase/conversion/Address.java | 35 +
.../AddressAction-conversion.properties | 6 +
.../showcase/conversion/AddressAction.java | 44 +
.../conversion/EnumTypeConverter.java | 55 +
.../showcase/conversion/OperationsEnum.java | 30 +
...OperationsEnumAction-conversion.properties | 4 +
.../conversion/OperationsEnumAction.java | 53 +
.../struts2/showcase/conversion/Person.java | 34 +
.../PersonAction-conversion.properties | 1 +
.../showcase/conversion/PersonAction.java | 43 +
.../struts2/showcase/dao/AbstractDao.java | 74 +
.../org/apache/struts2/showcase/dao/Dao.java | 50 +
.../struts2/showcase/dao/EmployeeDao.java | 64 +
.../apache/struts2/showcase/dao/SkillDao.java | 38 +
.../showcase/exception/CreateException.java | 40 +
.../showcase/exception/DeleteException.java | 41 +
.../exception/DuplicateKeyException.java | 41 +
.../showcase/exception/StorageException.java | 41 +
.../showcase/exception/UpdateException.java | 42 +
.../filedownload/FileDownloadAction.java | 41 +
.../showcase/fileupload/FileUploadAction.java | 82 +
.../freemarker/CustomFreemarkerManager.java | 54 +
.../CustomFreemarkerManagerUtil.java | 39 +
.../hangman/GetUpdatedHangmanAction.java | 39 +
.../hangman/GuessCharacterAction.java | 39 +
.../struts2/showcase/hangman/Hangman.java | 106 +
.../showcase/hangman/HangmanConstants.java | 6 +
.../showcase/hangman/HangmanException.java | 41 +
.../showcase/hangman/HangmanService.java | 31 +
.../hangman/PropertiesVocabSource.java | 68 +
.../showcase/hangman/StartHangmanAction.java | 58 +
.../struts2/showcase/hangman/Vocab.java | 83 +
.../struts2/showcase/hangman/VocabSource.java | 22 +
.../integration/EditGangsterAction.java | 41 +
.../showcase/integration/GangsterForm.java | 89 +
.../integration/SaveGangsterAction.java | 48 +
.../showcase/jsf/JsfEmployeeAction.java | 119 +
.../struts2/showcase/model/Employee.java | 173 +
.../struts2/showcase/model/IdEntity.java | 33 +
.../apache/struts2/showcase/model/Skill.java | 69 +
.../showcase/modelDriven/Gangster.java | 59 +
.../modelDriven/ModelDrivenAction.java | 42 +
.../person/CreatePerson-validation.xml | 8 +
.../struts2/showcase/person/CreatePerson.java | 48 +
.../person/EditPerson-conversion.properties | 3 +
.../struts2/showcase/person/EditPerson.java | 76 +
.../struts2/showcase/person/ListPeople.java | 52 +
.../showcase/person/Person-validation.xml | 13 +
.../struts2/showcase/person/Person.java | 83 +
.../showcase/person/PersonManager.java | 55 +
.../sitemesh/NoneDecoratorMapper.java | 20 +
.../showcase/source/ViewSourceAction.java | 217 +
.../tag/nonui/actionPrefix/SubmitAction.java | 22 +
.../tag/nonui/actiontag/ActionTagDemo.java | 35 +
.../iteratortag/AppendIteratorTagDemo.java | 77 +
.../IteratorGeneratorTagDemo-validation.xml | 22 +
.../iteratortag/IteratorGeneratorTagDemo.java | 66 +
.../iteratortag/MergeIteratorTagDemo.java | 78 +
.../iteratortag/SubsetIteratorTagDemo.java | 85 +
.../struts2/showcase/token/TokenAction.java | 81 +
.../struts2/showcase/tutorial/HelloName.java | 23 +
.../struts2/showcase/tutorial/HelloName2.java | 29 +
.../struts2/showcase/tutorial/HelloWorld.java | 23 +
.../AbstractValidationActionSupport.java | 33 +
...idatorsExampleAction-conversion.properties | 1 +
...ClientSideValidationExample-validation.xml | 74 +
...bmitFieldValidatorsExamples-validation.xml | 68 +
.../FieldValidatorsExampleAction.java | 104 +
.../FieldValidatorsExampleAction.properties | 1 +
...tNonFieldValidatorsExamples-validation.xml | 18 +
.../NonFieldValidatorsExampleAction.java | 57 +
.../validation/QuizAction-validation.xml | 23 +
.../showcase/validation/QuizAction.java | 61 +
.../validation/SubmitApplication.java | 57 +
.../User-userContext-validation.xml | 27 +
.../struts2/showcase/validation/User.java | 50 +
...itVisitorValidatorsExamples-validation.xml | 20 +
.../VisitorValidatorsExampleAction.java | 39 +
.../showcase/wait/LongProcessAction.java | 47 +
.../main/resources/globalMessages.properties | 7 +
.../resources/globalMessages_de.properties | 7 +
.../src/main/resources/log4j.properties | 31 +
.../myTheme/myAnotherTemplate.ftl | 6 +
.../struts2/showcase/DateAction.properties | 1 +
...-lotsOfRichtexteditorSubmit-validation.xml | 30 +
.../UITagExample-conversion.properties | 1 +
.../EmployeeAction-conversion.properties | 1 +
.../action/EmployeeAction-validation.xml | 21 +
.../showcase/action/EmployeeAction.properties | 9 +
.../action/EmployeeAction_de.properties | 9 +
.../action/SkillAction-validation.xml | 11 +
.../showcase/action/SkillAction.properties | 6 +
.../showcase/action/SkillAction_de.properties | 6 +
.../ajax/Example5Action-validation.xml | 19 +
.../ChatLoginAction-chatLogin-validation.xml | 14 +
.../chat/ChatMessage-conversion.properties | 1 +
.../CrudRoomAction-createRoom-validation.xml | 20 +
.../showcase/chat/Room-conversion.properties | 1 +
...oomAction-sendMessageToRoom-validation.xml | 15 +
.../PersonAction-conversion.properties | 1 +
.../person/CreatePerson-validation.xml | 8 +
.../person/EditPerson-conversion.properties | 3 +
.../showcase/person/Person-validation.xml | 13 +
.../IteratorGeneratorTagDemo-validation.xml | 22 +
...idatorsExampleAction-conversion.properties | 1 +
...ClientSideValidationExample-validation.xml | 74 +
...bmitFieldValidatorsExamples-validation.xml | 68 +
.../FieldValidatorsExampleAction.properties | 1 +
...tNonFieldValidatorsExamples-validation.xml | 18 +
.../validation/QuizAction-validation.xml | 23 +
...plication-submitApplication-validation.xml | 24 +
.../User-userContext-validation.xml | 27 +
...itVisitorValidatorsExamples-validation.xml | 20 +
.../main/resources/struts-actionchaining.xml | 21 +
.../src/main/resources/struts-ajax.xml | 71 +
.../src/main/resources/struts-chat.xml | 135 +
.../main/resources/struts-continuations.xml | 10 +
.../src/main/resources/struts-conversion.xml | 75 +
.../main/resources/struts-filedownload.xml | 24 +
.../src/main/resources/struts-fileupload.xml | 23 +
.../src/main/resources/struts-freemarker.xml | 14 +
.../src/main/resources/struts-hangman.xml | 48 +
.../src/main/resources/struts-integration.xml | 49 +
.../src/main/resources/struts-jsf.xml | 38 +
.../main/resources/struts-model-driven.xml | 20 +
.../src/main/resources/struts-person.xml | 31 +
.../src/main/resources/struts-tags-non-ui.xml | 123 +
.../src/main/resources/struts-tags-ui.xml | 61 +
.../src/main/resources/struts-tags.xml | 7 +
.../src/main/resources/struts-token.xml | 63 +
.../src/main/resources/struts-validation.xml | 124 +
.../src/main/resources/struts-wait.xml | 35 +
.../src/main/resources/struts.properties | 11 +
.../showcase/src/main/resources/struts.xml | 115 +
.../webapp/WEB-INF/applicationContext.xml | 117 +
.../src/main/webapp/WEB-INF/decorators.xml | 27 +
.../main/webapp/WEB-INF/decorators/main.jsp | 119 +
.../showcase/src/main/webapp/WEB-INF/dwr.xml | 25 +
.../webapp/WEB-INF/sitemesh-decorator.tld | 79 +
.../src/main/webapp/WEB-INF/sitemesh-page.tld | 95 +
.../src/main/webapp/WEB-INF/sitemesh.xml | 54 +
.../src/main/webapp/WEB-INF/validation.xml | 37 +
.../showcase/src/main/webapp/WEB-INF/web.xml | 151 +
.../actionchaining/actionChainingResult.jsp | 14 +
.../src/main/webapp/ajax/AjaxResult.jsp | 10 +
.../src/main/webapp/ajax/AjaxResult2.js | 2 +
.../src/main/webapp/ajax/AjaxResult3.jsp | 12 +
.../src/main/webapp/ajax/commonInclude.jsp | 4 +
.../showcase/src/main/webapp/ajax/footer.jsp | 9 +
.../showcase/src/main/webapp/ajax/index.jsp | 20 +
.../main/webapp/ajax/remotediv/example1.jsp | 24 +
.../main/webapp/ajax/remotediv/example2.jsp | 24 +
.../main/webapp/ajax/remotediv/example3.jsp | 24 +
.../main/webapp/ajax/remotediv/example4.jsp | 25 +
.../main/webapp/ajax/remotediv/example5.jsp | 24 +
.../main/webapp/ajax/remotediv/example6.jsp | 24 +
.../main/webapp/ajax/remotediv/example7.jsp | 24 +
.../main/webapp/ajax/remotediv/example8.jsp | 27 +
.../src/main/webapp/ajax/remotediv/index.jsp | 56 +
.../main/webapp/ajax/remoteforms/index.jsp | 111 +
.../main/webapp/ajax/remoteforms/test1.jsp | 18 +
.../main/webapp/ajax/remoteforms/test2.jsp | 6 +
.../main/webapp/ajax/remoteforms/test3.jsp | 8 +
.../src/main/webapp/ajax/remotelink/index.jsp | 112 +
.../main/webapp/ajax/tabbedpanel/example1.jsp | 113 +
.../main/webapp/ajax/tabbedpanel/example2.jsp | 52 +
.../main/webapp/ajax/tabbedpanel/example3.jsp | 57 +
.../main/webapp/ajax/tabbedpanel/example4.ftl | 18 +
.../main/webapp/ajax/tabbedpanel/example5.jsp | 27 +
.../webapp/ajax/tabbedpanel/example5Ok.jsp | 9 +
.../main/webapp/ajax/tabbedpanel/index.jsp | 33 +
.../ajax/tabbedpanel/nodecorate/panel1.ftl | 3 +
.../ajax/tabbedpanel/nodecorate/panel2.ftl | 7 +
.../tabbedpanel/nodecorate/panel2Submit.ftl | 2 +
.../ajax/tabbedpanel/nodecorate/panel3.ftl | 9 +
.../tabbedpanel/nodecorate/panel3Submit.ftl | 2 +
.../showcase/src/main/webapp/ajax/testjs.jsp | 14 +
.../src/main/webapp/ajax/tree/getCategory.jsp | 24 +
.../webapp/ajax/tree/partialChunkHeader.jsp | 6 +
.../src/main/webapp/ajax/tree/toggle.jsp | 12 +
.../src/main/webapp/ajax/tree/tree.jsp | 13 +
.../src/main/webapp/ajax/widgets/index.jsp | 36 +
.../src/main/webapp/chat/chatLogin.ftl | 16 +
.../src/main/webapp/chat/createRoom.ftl | 2 +
.../showcase/src/main/webapp/chat/index.jsp | 3 +
.../webapp/chat/messagesAvailableInRoom.ftl | 33 +
.../src/main/webapp/chat/roomSelection.ftl | 163 +
.../src/main/webapp/chat/roomsAvailable.ftl | 44 +
.../webapp/chat/sendMessageToRoomResult.ftl | 2 +
.../src/main/webapp/chat/showRoom.ftl | 160 +
.../src/main/webapp/chat/usersAvailable.ftl | 6 +
.../main/webapp/chat/usersAvailableInRoom.ftl | 8 +
.../src/main/webapp/continuations/guess.ftl | 18 +
.../main/webapp/conversion/Address.java.txt | 35 +
.../webapp/conversion/AddressAction.java.txt | 44 +
.../conversion/EnumTypeConverter.java.txt | 55 +
.../webapp/conversion/OperationsEnum.java.txt | 30 +
.../conversion/OperationsEnumAction.java.txt | 53 +
.../OperationsEnumActionConversion.txt | 4 +
.../main/webapp/conversion/Person.java.txt | 34 +
.../webapp/conversion/PersonAction.java.txt | 43 +
.../webapp/conversion/enterAddressInfo.jsp | 48 +
.../webapp/conversion/enterOperations.jsp | 31 +
.../webapp/conversion/enterPersonInfo.jsp | 58 +
.../src/main/webapp/conversion/index.jsp | 26 +
.../webapp/conversion/showAddressInfo.jsp | 15 +
.../main/webapp/conversion/showOperations.jsp | 17 +
.../main/webapp/conversion/showPersonInfo.jsp | 17 +
.../customTheme/ftlCustomTemplate.ftl | 7 +
.../customTheme/jspCustomTemplate.jsp | 8 +
trunk/apps/showcase/src/main/webapp/date.jsp | 2 +
.../main/webapp/empmanager/editEmployee.jsp | 41 +
.../src/main/webapp/empmanager/editSkill.jsp | 27 +
.../src/main/webapp/empmanager/index.jsp | 21 +
.../main/webapp/empmanager/listEmployees.jsp | 26 +
.../src/main/webapp/empmanager/listSkills.jsp | 24 +
.../src/main/webapp/filedownload/index.jsp | 14 +
.../main/webapp/fileupload/upload-success.jsp | 25 +
.../src/main/webapp/fileupload/upload.jsp | 21 +
.../customFreemarkerManagerUsage.ftl | 26 +
.../src/main/webapp/freemarker/index.jsp | 20 +
.../src/main/webapp/hangman/blank.ftl | 0
.../src/main/webapp/hangman/hangmanAjax.ftl | 232 +
.../src/main/webapp/hangman/hangmanMenu.ftl | 18 +
.../main/webapp/hangman/hangmanNonAjax.ftl | 135 +
.../webapp/hangman/images/Chalkboard_0.png | Bin 0 -> 1307 bytes
.../webapp/hangman/images/Chalkboard_1.png | Bin 0 -> 1226 bytes
.../webapp/hangman/images/Chalkboard_2.png | Bin 0 -> 1221 bytes
.../webapp/hangman/images/Chalkboard_3.png | Bin 0 -> 1227 bytes
.../webapp/hangman/images/Chalkboard_4.png | Bin 0 -> 1240 bytes
.../webapp/hangman/images/Chalkboard_5.png | Bin 0 -> 1260 bytes
.../webapp/hangman/images/Chalkboard_A.png | Bin 0 -> 1391 bytes
.../webapp/hangman/images/Chalkboard_B.png | Bin 0 -> 1460 bytes
.../webapp/hangman/images/Chalkboard_C.png | Bin 0 -> 1271 bytes
.../webapp/hangman/images/Chalkboard_D.png | Bin 0 -> 1420 bytes
.../webapp/hangman/images/Chalkboard_E.png | Bin 0 -> 1363 bytes
.../webapp/hangman/images/Chalkboard_F.png | Bin 0 -> 1270 bytes
.../webapp/hangman/images/Chalkboard_G.png | Bin 0 -> 1368 bytes
.../webapp/hangman/images/Chalkboard_H.png | Bin 0 -> 1310 bytes
.../webapp/hangman/images/Chalkboard_I.png | Bin 0 -> 1296 bytes
.../webapp/hangman/images/Chalkboard_J.png | Bin 0 -> 1225 bytes
.../webapp/hangman/images/Chalkboard_K.png | Bin 0 -> 1431 bytes
.../webapp/hangman/images/Chalkboard_L.png | Bin 0 -> 1252 bytes
.../webapp/hangman/images/Chalkboard_M.png | Bin 0 -> 1353 bytes
.../webapp/hangman/images/Chalkboard_N.png | Bin 0 -> 1419 bytes
.../webapp/hangman/images/Chalkboard_O.png | Bin 0 -> 1412 bytes
.../webapp/hangman/images/Chalkboard_P.png | Bin 0 -> 1371 bytes
.../webapp/hangman/images/Chalkboard_Q.png | Bin 0 -> 1474 bytes
.../webapp/hangman/images/Chalkboard_R.png | Bin 0 -> 1446 bytes
.../webapp/hangman/images/Chalkboard_S.png | Bin 0 -> 1393 bytes
.../webapp/hangman/images/Chalkboard_T.png | Bin 0 -> 1284 bytes
.../webapp/hangman/images/Chalkboard_U.png | Bin 0 -> 1377 bytes
.../webapp/hangman/images/Chalkboard_V.png | Bin 0 -> 1322 bytes
.../webapp/hangman/images/Chalkboard_W.png | Bin 0 -> 1440 bytes
.../webapp/hangman/images/Chalkboard_X.png | Bin 0 -> 1397 bytes
.../webapp/hangman/images/Chalkboard_Y.png | Bin 0 -> 1318 bytes
.../webapp/hangman/images/Chalkboard_Z.png | Bin 0 -> 1353 bytes
.../hangman/images/Chalkboard_underscroll.png | Bin 0 -> 1110 bytes
.../src/main/webapp/hangman/images/choose.png | Bin 0 -> 3321 bytes
.../src/main/webapp/hangman/images/guess.png | Bin 0 -> 2900 bytes
.../webapp/hangman/images/guesses-left.png | Bin 0 -> 2372 bytes
.../main/webapp/hangman/images/hangman.png | Bin 0 -> 3850 bytes
.../webapp/hangman/images/letter-spacer.png | Bin 0 -> 926 bytes
.../main/webapp/hangman/images/play-again.png | Bin 0 -> 8607 bytes
.../webapp/hangman/images/scaffold_-1.png | Bin 0 -> 9806 bytes
.../main/webapp/hangman/images/scaffold_0.png | Bin 0 -> 9017 bytes
.../main/webapp/hangman/images/scaffold_1.png | Bin 0 -> 7999 bytes
.../main/webapp/hangman/images/scaffold_2.png | Bin 0 -> 7260 bytes
.../main/webapp/hangman/images/scaffold_3.png | Bin 0 -> 6715 bytes
.../main/webapp/hangman/images/scaffold_4.png | Bin 0 -> 6268 bytes
.../main/webapp/hangman/images/scaffold_5.png | Bin 0 -> 4267 bytes
.../src/main/webapp/hangman/images/start.png | Bin 0 -> 5145 bytes
.../main/webapp/hangman/images/you-lose.png | Bin 0 -> 7500 bytes
.../main/webapp/hangman/images/you-win.png | Bin 0 -> 6544 bytes
.../showcase/src/main/webapp/hangman/test.ftl | 21 +
.../hangman/updateCharacterAvailable.ftl | 47 +
.../main/webapp/hangman/updateGuessLeft.ftl | 7 +
.../main/webapp/hangman/updateScaffold.ftl | 3 +
.../webapp/hangman/updateVocabCharacters.ftl | 20 +
trunk/apps/showcase/src/main/webapp/help.jsp | 31 +
.../src/main/webapp/images/struts-power.gif | Bin 0 -> 1798 bytes
.../src/main/webapp/images/struts.gif | Bin 0 -> 4720 bytes
trunk/apps/showcase/src/main/webapp/index.jsp | 1 +
.../main/webapp/integration/modelDriven.jsp | 31 +
.../webapp/integration/modelDrivenResult.jsp | 24 +
.../src/main/webapp/jsf/employee/edit.jsp | 106 +
.../src/main/webapp/jsf/employee/list.jsp | 69 +
.../showcase/src/main/webapp/jsf/index.jsp | 24 +
.../main/webapp/modelDriven/modelDriven.jsp | 31 +
.../webapp/modelDriven/modelDrivenResult.jsp | 24 +
.../src/main/webapp/person/editPeople.jsp | 41 +
.../showcase/src/main/webapp/person/index.jsp | 12 +
.../src/main/webapp/person/listPeople.ftl | 28 +
.../src/main/webapp/person/newPerson.ftl | 19 +
.../showcase/src/main/webapp/showcase.jsp | 82 +
.../showcase/src/main/webapp/styles/forms.css | 102 +
.../main/webapp/styles/layout-navtop-1col.css | 33 +
.../webapp/styles/layout-navtop-localleft.css | 36 +
.../src/main/webapp/styles/layout.css | 136 +
.../showcase/src/main/webapp/styles/main.css | 5 +
.../src/main/webapp/styles/nav-horizontal.css | 80 +
.../showcase/src/main/webapp/styles/tools.css | 68 +
.../showcase/src/main/webapp/styles/typo.css | 195 +
.../showcase/src/main/webapp/tags/index.jsp | 16 +
.../tags/non-ui/actionPrefix/actionPrefix.ftl | 19 +
.../actionPrefix/actionPrefixExample.ftl | 45 +
.../webapp/tags/non-ui/actionPrefix/index.jsp | 13 +
.../tags/non-ui/actionPrefix/methodPrefix.ftl | 19 +
.../tags/non-ui/actionPrefix/normalSubmit.ftl | 17 +
.../actionPrefix/redirectActionPrefix.ftl | 22 +
.../tags/non-ui/actionTag/includedPage.jsp | 1 +
.../tags/non-ui/actionTag/includedPage2.jsp | 2 +
.../tags/non-ui/actionTag/includedPage3.jsp | 2 +
.../non-ui/actionTag/showActionTagDemo.jsp | 43 +
.../src/main/webapp/tags/non-ui/date.jsp | 104 +
.../src/main/webapp/tags/non-ui/debug.jsp | 20 +
.../main/webapp/tags/non-ui/ifTag/testIf.ftl | 607 +
.../main/webapp/tags/non-ui/ifTag/testIf.jsp | 616 +
.../src/main/webapp/tags/non-ui/index.jsp | 24 +
.../appendIteratorTagDemoResult.jsp | 25 +
.../iteratorGeneratorTagDemoResult.jsp | 19 +
.../mergeIteratorTagDemoResult.jsp | 25 +
.../iteratorTag/showAppendIteratorTagDemo.jsp | 19 +
.../showIteratorGeneratorTagDemo.jsp | 21 +
.../iteratorTag/showMergeIteratorTagDemo.jsp | 17 +
.../iteratorTag/subsetIteratorTagDemo.jsp | 20 +
.../subsetIteratorTagDemoResult.jsp | 21 +
.../webapp/tags/ui/componentTagExample.jsp | 62 +
.../main/webapp/tags/ui/dynamicTreeSelect.jsp | 6 +
.../src/main/webapp/tags/ui/example.jsp | 126 +
.../src/main/webapp/tags/ui/example.vm | 32 +
.../main/webapp/tags/ui/exampleSubmited.jsp | 43 +
.../main/webapp/tags/ui/exampleSubmited.vm | 47 +
.../webapp/tags/ui/images/backgroundImage.jpg | Bin 0 -> 13192 bytes
.../main/webapp/tags/ui/images/leopard.jpg | Bin 0 -> 3850 bytes
.../src/main/webapp/tags/ui/index.jsp | 20 +
.../tags/ui/lotsOfOptiontransferselect.jsp | 109 +
.../ui/lotsOfOptiontransferselectSubmit.jsp | 101 +
.../main/webapp/tags/ui/staticTreeSelect.jsp | 28 +
.../webapp/tags/ui/treeExampleDynamic.jsp | 47 +
.../main/webapp/tags/ui/treeExampleStatic.jsp | 53 +
.../main/webapp/template/xhtml/mytemplate.jsp | 9 +
.../src/main/webapp/token/doublePost.jsp | 15 +
.../src/main/webapp/token/example1.jsp | 24 +
.../src/main/webapp/token/example2.jsp | 24 +
.../src/main/webapp/token/example3.jsp | 24 +
.../src/main/webapp/token/example4.ftl | 26 +
.../showcase/src/main/webapp/token/index.jsp | 33 +
.../src/main/webapp/token/transferDone.jsp | 25 +
.../clientSideValidationExample.jsp | 55 +
.../validation/fieldValidatorsExample.jsp | 55 +
.../src/main/webapp/validation/footer.jsp | 9 +
.../src/main/webapp/validation/index.jsp | 42 +
.../validation/nonFieldValidatorsExample.jsp | 38 +
.../src/main/webapp/validation/quiz-ajax.jsp | 23 +
.../src/main/webapp/validation/quiz-basic.jsp | 27 +
.../webapp/validation/quiz-client-css.jsp | 24 +
.../main/webapp/validation/quiz-client.jsp | 24 +
.../main/webapp/validation/quiz-success.jsp | 14 +
.../storeErrorsAcrossRequestCancel.jsp | 21 +
.../storeErrorsAcrossRequestExample.jsp | 35 +
.../validation/storeErrorsAcrossRequestOk.jsp | 23 +
.../successClientSideValidationExample.jsp | 53 +
.../successFieldValidatorsExample.jsp | 48 +
.../successNonFieldValidatorsExample.jsp | 33 +
.../successVisitorValidatorsExample.jsp | 35 +
.../validation/validationExamplesStyles.css | 11 +
.../validation/visitorValidatorsExample.jsp | 36 +
.../showcase/src/main/webapp/viewSource.jsp | 53 +
.../src/main/webapp/wait/complete.jsp | 13 +
.../src/main/webapp/wait/example1.jsp | 16 +
.../src/main/webapp/wait/example2.jsp | 17 +
.../src/main/webapp/wait/example3.jsp | 18 +
.../showcase/src/main/webapp/wait/index.jsp | 19 +
.../showcase/src/main/webapp/wait/wait.jsp | 16 +
.../struts2/showcase/tutorial/HelloTest.java | 18 +
trunk/assembly/pom.xml | 442 +
trunk/assembly/src/main/assembly/all.xml | 188 +
trunk/assembly/src/main/assembly/apps.xml | 43 +
trunk/assembly/src/main/assembly/lib.xml | 43 +
trunk/assembly/src/main/assembly/src.xml | 121 +
trunk/assembly/src/main/resources/LICENSE.txt | 174 +
trunk/assembly/src/main/resources/NOTICE.txt | 3 +
trunk/assembly/src/main/resources/build.xml | 53 +
trunk/backport/ASM-LICENSE.txt | 28 +
trunk/backport/LICENSE.txt | 29 +
trunk/backport/RETROTRANSLATOR-LICENSE.txt | 29 +
trunk/backport/S2-FOR-J4-README.txt | 22 +
trunk/backport/STRUTS-LICENSE.txt | 174 +
trunk/backport/XWORK-LICENSE.txt | 50 +
trunk/backport/backport-util-concurrent.jar | Bin 0 -> 326319 bytes
trunk/backport/readme.html | 549 +
.../retrotranslator-runtime-1.0.7.jar | Bin 0 -> 168707 bytes
.../retrotranslator-runtime-1.0.8.jar | Bin 0 -> 173833 bytes
.../retrotranslator-transformer-1.0.8.jar | Bin 0 -> 88716 bytes
trunk/backport/translate.bat | 4 +
trunk/core/pom.xml | 275 +
trunk/core/src/main/etc/taglib-settings.xml | 5 +
.../java/org/apache/struts2/RequestUtils.java | 53 +
.../apache/struts2/ServletActionContext.java | 146 +
.../org/apache/struts2/StrutsConstants.java | 133 +
.../org/apache/struts2/StrutsException.java | 101 +
.../org/apache/struts2/StrutsStatics.java | 65 +
.../org/apache/struts2/StrutsTestCase.java | 60 +
.../struts2/components/ActionComponent.java | 294 +
.../struts2/components/ActionError.java | 62 +
.../struts2/components/ActionMessage.java | 58 +
.../org/apache/struts2/components/Anchor.java | 139 +
.../struts2/components/AppendIterator.java | 170 +
.../org/apache/struts2/components/Bean.java | 146 +
.../apache/struts2/components/Checkbox.java | 82 +
.../struts2/components/CheckboxList.java | 53 +
.../struts2/components/ClosingUIBean.java | 65 +
.../apache/struts2/components/ComboBox.java | 211 +
.../apache/struts2/components/Component.java | 463 +
.../org/apache/struts2/components/Date.java | 383 +
.../apache/struts2/components/DatePicker.java | 177 +
.../org/apache/struts2/components/Debug.java | 96 +
.../org/apache/struts2/components/Div.java | 159 +
.../struts2/components/DoubleListUIBean.java | 667 +
.../struts2/components/DoubleSelect.java | 60 +
.../org/apache/struts2/components/Else.java | 69 +
.../org/apache/struts2/components/ElseIf.java | 104 +
.../apache/struts2/components/FieldError.java | 107 +
.../org/apache/struts2/components/File.java | 103 +
.../org/apache/struts2/components/Form.java | 509 +
.../apache/struts2/components/FormButton.java | 174 +
.../struts2/components/GenericUIBean.java | 125 +
.../org/apache/struts2/components/Head.java | 134 +
.../org/apache/struts2/components/Hidden.java | 59 +
.../org/apache/struts2/components/I18n.java | 130 +
.../org/apache/struts2/components/If.java | 95 +
.../apache/struts2/components/Include.java | 403 +
.../struts2/components/IteratorComponent.java | 290 +
.../org/apache/struts2/components/Label.java | 87 +
.../apache/struts2/components/ListUIBean.java | 156 +
.../struts2/components/MergeIterator.java | 182 +
.../apache/struts2/components/OptGroup.java | 149 +
.../components/OptionTransferSelect.java | 545 +
.../org/apache/struts2/components/Panel.java | 120 +
.../org/apache/struts2/components/Param.java | 159 +
.../apache/struts2/components/Password.java | 74 +
.../apache/struts2/components/Property.java | 162 +
.../org/apache/struts2/components/Push.java | 148 +
.../org/apache/struts2/components/Radio.java | 59 +
.../struts2/components/RemoteCallUIBean.java | 99 +
.../org/apache/struts2/components/Reset.java | 99 +
.../org/apache/struts2/components/Select.java | 153 +
.../org/apache/struts2/components/Set.java | 142 +
.../org/apache/struts2/components/Submit.java | 287 +
.../struts2/components/TabbedPanel.java | 156 +
.../org/apache/struts2/components/Text.java | 189 +
.../apache/struts2/components/TextArea.java | 110 +
.../apache/struts2/components/TextField.java | 111 +
.../apache/struts2/components/TimePicker.java | 153 +
.../org/apache/struts2/components/Token.java | 116 +
.../org/apache/struts2/components/Tree.java | 498 +
.../apache/struts2/components/TreeNode.java | 102 +
.../org/apache/struts2/components/UIBean.java | 1090 ++
.../org/apache/struts2/components/URL.java | 414 +
.../struts2/components/UpDownSelect.java | 230 +
.../components/table/AbstractFilterModel.java | 101 +
.../components/table/RenderFilterModel.java | 44 +
.../components/table/SortFilterModel.java | 196 +
.../components/table/SortableTableModel.java | 37 +
.../struts2/components/table/WebTable.java | 360 +
.../components/table/WebTableColumn.java | 81 +
.../table/renderer/AbstractCellRenderer.java | 71 +
.../table/renderer/BooleanCellRenderer.java | 62 +
.../table/renderer/CellRenderer.java | 27 +
.../table/renderer/DateCellRenderer.java | 61 +
.../table/renderer/DefaultCellRenderer.java | 39 +
.../table/renderer/FixedTextCellRenderer.java | 46 +
.../table/renderer/LinkCellRenderer.java | 240 +
.../table/renderer/NumericCellRenderer.java | 100 +
.../components/table/renderer/package.html | 1 +
.../template/BaseTemplateEngine.java | 101 +
.../template/FreemarkerTemplateEngine.java | 148 +
.../template/JspTemplateEngine.java | 83 +
.../struts2/components/template/Template.java | 88 +
.../components/template/TemplateEngine.java | 43 +
.../template/TemplateEngineManager.java | 79 +
.../template/TemplateRenderingContext.java | 73 +
.../template/VelocityTemplateEngine.java | 101 +
.../struts2/config/DefaultSettings.java | 145 +
.../struts2/config/DelegatingSettings.java | 150 +
.../struts2/config/PropertiesSettings.java | 106 +
.../config/ServletContextSingleton.java | 88 +
.../org/apache/struts2/config/Settings.java | 228 +
.../StrutsXmlConfigurationProvider.java | 119 +
.../org/apache/struts2/config/package.html | 1 +
.../dispatcher/ActionContextCleanUp.java | 155 +
.../struts2/dispatcher/ApplicationMap.java | 191 +
.../dispatcher/DefaultActionSupport.java | 69 +
.../apache/struts2/dispatcher/Dispatcher.java | 670 +
.../dispatcher/DispatcherListener.java | 39 +
.../struts2/dispatcher/FilterDispatcher.java | 399 +
.../FilterDispatcherCompatWeblogic61.java | 104 +
.../struts2/dispatcher/HttpHeaderResult.java | 157 +
.../struts2/dispatcher/PlainTextResult.java | 167 +
.../apache/struts2/dispatcher/RequestMap.java | 146 +
.../ServletActionRedirectResult.java | 240 +
.../dispatcher/ServletDispatcherResult.java | 142 +
.../dispatcher/ServletRedirectResult.java | 146 +
.../apache/struts2/dispatcher/SessionMap.java | 204 +
.../struts2/dispatcher/StreamResult.java | 239 +
.../dispatcher/StrutsRequestWrapper.java | 85 +
.../dispatcher/StrutsResultSupport.java | 220 +
.../struts2/dispatcher/VelocityResult.java | 222 +
.../dispatcher/mapper/ActionMapper.java | 59 +
.../mapper/ActionMapperFactory.java | 66 +
.../dispatcher/mapper/ActionMapping.java | 141 +
.../mapper/DefaultActionMapper.java | 441 +
.../mapper/RestfulActionMapper.java | 123 +
.../multipart/JakartaMultiPartRequest.java | 281 +
.../multipart/MultiPartRequest.java | 128 +
.../multipart/MultiPartRequestWrapper.java | 305 +
.../struts2/dispatcher/multipart/package.html | 1 +
.../apache/struts2/dispatcher/package.html | 1 +
.../struts2/impl/ActionContextImpl.java | 64 +
.../struts2/impl/InterceptorAdapter.java | 49 +
.../org/apache/struts2/impl/MessagesImpl.java | 134 +
.../struts2/impl/RequestContextImpl.java | 177 +
.../apache/struts2/impl/ResultAdapter.java | 20 +
.../struts2/impl/StrutsActionProxy.java | 35 +
.../impl/StrutsActionProxyFactory.java | 22 +
.../struts2/impl/StrutsObjectFactory.java | 84 +
.../struts2/impl/ValueStackAdapter.java | 58 +
.../struts2/interceptor/ApplicationAware.java | 39 +
.../interceptor/BackgroundProcess.java | 133 +
.../interceptor/CheckboxInterceptor.java | 91 +
.../interceptor/CreateSessionInterceptor.java | 92 +
.../ExecuteAndWaitInterceptor.java | 333 +
.../interceptor/FileUploadInterceptor.java | 369 +
.../interceptor/MessageStoreInterceptor.java | 330 +
.../struts2/interceptor/NoParameters.java | 29 +
.../struts2/interceptor/ParameterAware.java | 42 +
.../struts2/interceptor/PrincipalAware.java | 30 +
.../struts2/interceptor/PrincipalProxy.java | 86 +
.../ProfilingActivationInterceptor.java | 63 +
.../struts2/interceptor/RequestAware.java | 38 +
.../struts2/interceptor/ScopeInterceptor.java | 441 +
.../interceptor/ServletConfigInterceptor.java | 158 +
.../interceptor/ServletRequestAware.java | 40 +
.../interceptor/ServletResponseAware.java | 40 +
.../struts2/interceptor/SessionAware.java | 40 +
.../StrutsConversionErrorInterceptor.java | 122 +
.../struts2/interceptor/TokenInterceptor.java | 171 +
.../TokenSessionStoreInterceptor.java | 152 +
.../debugging/DebuggingInterceptor.java | 358 +
.../debugging/PrettyPrintWriter.java | 174 +
.../portlet/PortletActionConstants.java | 103 +
.../portlet/PortletApplicationMap.java | 203 +
.../struts2/portlet/PortletRequestMap.java | 164 +
.../struts2/portlet/PortletSessionMap.java | 168 +
.../portlet/context/PortletActionContext.java | 193 +
.../portlet/context/PreparatorServlet.java | 63 +
.../context/ServletContextHolderListener.java | 60 +
.../DirectRenderFromEventAction.java | 70 +
.../portlet/dispatcher/Jsr168Dispatcher.java | 597 +
.../struts2/portlet/result/PortletResult.java | 243 +
.../portlet/result/PortletVelocityResult.java | 293 +
.../portlet/util/PortletUrlHelper.java | 299 +
.../spring/StrutsSpringObjectFactory.java | 85 +
...xternalReferenceResolverSetupListener.java | 114 +
.../struts2/util/AppendIteratorFilter.java | 81 +
.../org/apache/struts2/util/AttributeMap.java | 134 +
.../apache/struts2/util/ClassLoaderUtils.java | 131 +
.../org/apache/struts2/util/ContainUtil.java | 66 +
.../java/org/apache/struts2/util/Counter.java | 120 +
.../apache/struts2/util/DateFormatter.java | 90 +
.../util/FastByteArrayOutputStream.java | 217 +
.../struts2/util/InvocationSessionStore.java | 118 +
.../struts2/util/IteratorFilterSupport.java | 56 +
.../struts2/util/IteratorGenerator.java | 138 +
.../org/apache/struts2/util/ListEntry.java | 49 +
.../org/apache/struts2/util/MakeIterator.java | 106 +
.../struts2/util/MergeIteratorFilter.java | 87 +
.../util/ObjectFactoryDestroyable.java | 30 +
.../util/ObjectFactoryInitializable.java | 30 +
.../struts2/util/ObjectFactoryLifecycle.java | 30 +
.../org/apache/struts2/util/PrefixTrie.java | 63 +
.../ResolverSetupServletContextListener.java | 87 +
.../struts2/util/ServletContextAware.java | 29 +
.../struts2/util/SortIteratorFilter.java | 105 +
.../java/org/apache/struts2/util/Sorter.java | 149 +
.../struts2/util/StrutsTypeConverter.java | 89 +
.../org/apache/struts2/util/StrutsUtil.java | 290 +
.../struts2/util/SubsetIteratorFilter.java | 173 +
.../org/apache/struts2/util/TabbedPane.java | 65 +
.../java/org/apache/struts2/util/Timer.java | 48 +
.../org/apache/struts2/util/TokenHelper.java | 183 +
.../java/org/apache/struts2/util/URLBean.java | 96 +
.../struts2/util/VelocityStrutsUtil.java | 55 +
.../struts2/validators/DWRValidator.java | 134 +
.../struts2/views/JspSupportServlet.java | 37 +
.../views/freemarker/FreemarkerManager.java | 342 +
.../views/freemarker/FreemarkerResult.java | 280 +
.../freemarker/PortletFreemarkerResult.java | 283 +
.../views/freemarker/ScopesHashModel.java | 118 +
.../views/freemarker/StrutsBeanWrapper.java | 95 +
.../freemarker/StrutsClassTemplateLoader.java | 32 +
.../freemarker/tags/ActionErrorModel.java | 39 +
.../freemarker/tags/ActionMessageModel.java | 39 +
.../views/freemarker/tags/ActionModel.java | 39 +
.../views/freemarker/tags/AnchorModel.java | 39 +
.../views/freemarker/tags/BeanModel.java | 39 +
.../views/freemarker/tags/CallbackWriter.java | 96 +
.../freemarker/tags/CheckboxListModel.java | 39 +
.../views/freemarker/tags/CheckboxModel.java | 39 +
.../views/freemarker/tags/ComboBoxModel.java | 39 +
.../views/freemarker/tags/ComponentModel.java | 39 +
.../views/freemarker/tags/DateModel.java | 41 +
.../freemarker/tags/DatePickerModel.java | 39 +
.../views/freemarker/tags/DivModel.java | 39 +
.../freemarker/tags/DoubleSelectModel.java | 39 +
.../views/freemarker/tags/ElseIfModel.java | 41 +
.../views/freemarker/tags/ElseModel.java | 42 +
.../freemarker/tags/FieldErrorModel.java | 39 +
.../views/freemarker/tags/FileModel.java | 39 +
.../views/freemarker/tags/FormModel.java | 39 +
.../views/freemarker/tags/HeadModel.java | 39 +
.../views/freemarker/tags/HiddenModel.java | 39 +
.../views/freemarker/tags/I18nModel.java | 39 +
.../views/freemarker/tags/IfModel.java | 41 +
.../views/freemarker/tags/IncludeModel.java | 39 +
.../views/freemarker/tags/IteratorModel.java | 39 +
.../views/freemarker/tags/LabelModel.java | 39 +
.../views/freemarker/tags/OptGroupModel.java | 40 +
.../tags/OptionTransferSelectModel.java | 41 +
.../views/freemarker/tags/PanelModel.java | 39 +
.../views/freemarker/tags/ParamModel.java | 39 +
.../views/freemarker/tags/PasswordModel.java | 39 +
.../views/freemarker/tags/PropertyModel.java | 39 +
.../views/freemarker/tags/PushModel.java | 39 +
.../views/freemarker/tags/RadioModel.java | 39 +
.../views/freemarker/tags/ResetModel.java | 39 +
.../views/freemarker/tags/SelectModel.java | 39 +
.../views/freemarker/tags/SetModel.java | 39 +
.../views/freemarker/tags/StrutsModels.java | 463 +
.../views/freemarker/tags/SubmitModel.java | 39 +
.../freemarker/tags/TabbedPanelModel.java | 39 +
.../views/freemarker/tags/TagModel.java | 102 +
.../views/freemarker/tags/TextAreaModel.java | 39 +
.../views/freemarker/tags/TextFieldModel.java | 39 +
.../views/freemarker/tags/TextModel.java | 39 +
.../freemarker/tags/TimePickerModel.java | 21 +
.../views/freemarker/tags/TokenModel.java | 39 +
.../views/freemarker/tags/TreeModel.java | 41 +
.../views/freemarker/tags/TreeNodeModel.java | 40 +
.../views/freemarker/tags/URLModel.java | 39 +
.../freemarker/tags/UpDownSelectModel.java | 42 +
.../views/freemarker/tags/WebTableModel.java | 39 +
.../apache/struts2/views/jsp/ActionTag.java | 75 +
.../org/apache/struts2/views/jsp/BeanTag.java | 55 +
.../views/jsp/ComponentTagSupport.java | 60 +
.../org/apache/struts2/views/jsp/DateTag.java | 63 +
.../apache/struts2/views/jsp/ElseIfTag.java | 48 +
.../org/apache/struts2/views/jsp/ElseTag.java | 39 +
.../org/apache/struts2/views/jsp/I18nTag.java | 51 +
.../org/apache/struts2/views/jsp/IfTag.java | 49 +
.../apache/struts2/views/jsp/IncludeTag.java | 51 +
.../struts2/views/jsp/IteratorStatus.java | 74 +
.../apache/struts2/views/jsp/IteratorTag.java | 81 +
.../apache/struts2/views/jsp/ParamTag.java | 57 +
.../apache/struts2/views/jsp/PropertyTag.java | 64 +
.../org/apache/struts2/views/jsp/PushTag.java | 51 +
.../org/apache/struts2/views/jsp/SetTag.java | 64 +
.../views/jsp/StrutsBodyTagSupport.java | 124 +
.../apache/struts2/views/jsp/TagUtils.java | 104 +
.../org/apache/struts2/views/jsp/TextTag.java | 51 +
.../org/apache/struts2/views/jsp/URLTag.java | 120 +
.../views/jsp/iterator/AppendIteratorTag.java | 44 +
.../jsp/iterator/IteratorGeneratorTag.java | 253 +
.../views/jsp/iterator/MergeIteratorTag.java | 45 +
.../views/jsp/iterator/SortIteratorTag.java | 152 +
.../views/jsp/iterator/SubsetIteratorTag.java | 288 +
.../org/apache/struts2/views/jsp/package.html | 1 +
.../views/jsp/ui/AbstractClosingTag.java | 36 +
.../views/jsp/ui/AbstractDoubleListTag.java | 369 +
.../struts2/views/jsp/ui/AbstractListTag.java | 49 +
.../views/jsp/ui/AbstractRequiredListTag.java | 34 +
.../struts2/views/jsp/ui/AbstractUITag.java | 225 +
.../struts2/views/jsp/ui/ActionErrorTag.java | 40 +
.../views/jsp/ui/ActionMessageTag.java | 39 +
.../struts2/views/jsp/ui/AnchorTag.java | 83 +
.../struts2/views/jsp/ui/CheckboxListTag.java | 39 +
.../struts2/views/jsp/ui/CheckboxTag.java | 51 +
.../struts2/views/jsp/ui/ComboBoxTag.java | 80 +
.../struts2/views/jsp/ui/ComponentTag.java | 38 +
.../struts2/views/jsp/ui/DatePickerTag.java | 71 +
.../apache/struts2/views/jsp/ui/DebugTag.java | 19 +
.../apache/struts2/views/jsp/ui/DivTag.java | 90 +
.../struts2/views/jsp/ui/DoubleSelectTag.java | 50 +
.../struts2/views/jsp/ui/FieldErrorTag.java | 39 +
.../apache/struts2/views/jsp/ui/FileTag.java | 58 +
.../apache/struts2/views/jsp/ui/FormTag.java | 106 +
.../apache/struts2/views/jsp/ui/HeadTag.java | 63 +
.../struts2/views/jsp/ui/HiddenTag.java | 39 +
.../apache/struts2/views/jsp/ui/LabelTag.java | 51 +
.../apache/struts2/views/jsp/ui/OgnlTool.java | 45 +
.../struts2/views/jsp/ui/OptGroupTag.java | 76 +
.../views/jsp/ui/OptionTransferSelectTag.java | 225 +
.../apache/struts2/views/jsp/ui/PanelTag.java | 63 +
.../struts2/views/jsp/ui/PasswordTag.java | 55 +
.../apache/struts2/views/jsp/ui/RadioTag.java | 39 +
.../apache/struts2/views/jsp/ui/ResetTag.java | 70 +
.../struts2/views/jsp/ui/SelectTag.java | 77 +
.../struts2/views/jsp/ui/SubmitTag.java | 113 +
.../struts2/views/jsp/ui/TabbedPanelTag.java | 50 +
.../struts2/views/jsp/ui/TextFieldTag.java | 70 +
.../struts2/views/jsp/ui/TextareaTag.java | 71 +
.../struts2/views/jsp/ui/TimePickerTag.java | 69 +
.../apache/struts2/views/jsp/ui/TokenTag.java | 39 +
.../struts2/views/jsp/ui/TreeNodeTag.java | 53 +
.../apache/struts2/views/jsp/ui/TreeTag.java | 302 +
.../struts2/views/jsp/ui/UpDownSelectTag.java | 120 +
.../views/jsp/ui/table/WebTableTag.java | 71 +
.../struts2/views/util/ContextUtil.java | 94 +
.../struts2/views/util/ResourceUtil.java | 35 +
.../apache/struts2/views/util/TextUtil.java | 242 +
.../apache/struts2/views/util/UrlHelper.java | 307 +
.../apache/struts2/views/util/package.html | 1 +
.../views/velocity/StrutsResourceLoader.java | 48 +
.../views/velocity/StrutsVelocityContext.java | 112 +
.../views/velocity/StrutsVelocityServlet.java | 135 +
.../views/velocity/VelocityManager.java | 672 +
.../components/AbstractDirective.java | 126 +
.../velocity/components/ActionDirective.java | 39 +
.../components/ActionErrorDirective.java | 39 +
.../components/ActionMessageDirective.java | 39 +
.../velocity/components/AnchorDirective.java | 43 +
.../velocity/components/BeanDirective.java | 39 +
.../components/CheckBoxDirective.java | 39 +
.../components/CheckBoxListDirective.java | 39 +
.../components/ComboBoxDirective.java | 39 +
.../components/ComponentDirective.java | 43 +
.../velocity/components/DateDirective.java | 40 +
.../components/DatePickerDirective.java | 39 +
.../velocity/components/DivDirective.java | 39 +
.../components/DoubleSelectDirective.java | 39 +
.../components/FieldErrorDirective.java | 39 +
.../velocity/components/FileDirective.java | 39 +
.../velocity/components/FormDirective.java | 43 +
.../velocity/components/HeadDirective.java | 39 +
.../velocity/components/HiddenDirective.java | 39 +
.../velocity/components/I18nDirective.java | 39 +
.../velocity/components/IncludeDirective.java | 39 +
.../velocity/components/LabelDirective.java | 39 +
.../components/OptGroupDirective.java | 41 +
.../OptionTransferSelectDirective.java | 41 +
.../velocity/components/PanelDirective.java | 39 +
.../velocity/components/ParamDirective.java | 39 +
.../components/PasswordDirective.java | 39 +
.../components/PropertyDirective.java | 38 +
.../velocity/components/PushDirective.java | 39 +
.../velocity/components/RadioDirective.java | 39 +
.../velocity/components/ResetDirective.java | 39 +
.../velocity/components/SelectDirective.java | 39 +
.../velocity/components/SetDirective.java | 39 +
.../velocity/components/SubmitDirective.java | 39 +
.../components/TabbedPanelDirective.java | 39 +
.../components/TextAreaDirective.java | 39 +
.../velocity/components/TextDirective.java | 39 +
.../components/TextFieldDirective.java | 39 +
.../velocity/components/TokenDirective.java | 39 +
.../velocity/components/TreeDirective.java | 40 +
.../components/TreeNodeDirective.java | 41 +
.../velocity/components/URLDirective.java | 39 +
.../components/UpDownSelectDirective.java | 41 +
.../components/WebTableDirective.java | 39 +
.../struts2/views/velocity/package.html | 1 +
.../views/xslt/AbstractAdapterElement.java | 137 +
.../views/xslt/AbstractAdapterNode.java | 380 +
.../struts2/views/xslt/AdapterFactory.java | 239 +
.../struts2/views/xslt/AdapterNode.java | 75 +
.../struts2/views/xslt/ArrayAdapter.java | 57 +
.../struts2/views/xslt/BeanAdapter.java | 172 +
.../struts2/views/xslt/CollectionAdapter.java | 57 +
.../apache/struts2/views/xslt/MapAdapter.java | 83 +
.../struts2/views/xslt/ProxyAttrAdapter.java | 82 +
.../views/xslt/ProxyElementAdapter.java | 165 +
.../struts2/views/xslt/ProxyNamedNodeMap.java | 78 +
.../struts2/views/xslt/ProxyNodeAdapter.java | 131 +
.../views/xslt/ProxyTextNodeAdapter.java | 94 +
.../views/xslt/ServletURIResolver.java | 70 +
.../views/xslt/SimpleAdapterDocument.java | 254 +
.../struts2/views/xslt/SimpleNodeList.java | 55 +
.../struts2/views/xslt/SimpleTextNode.java | 102 +
.../struts2/views/xslt/StringAdapter.java | 112 +
.../apache/struts2/views/xslt/XSLTResult.java | 347 +
.../apache/struts2/views/xslt/package.html | 24 +
.../main/resources/META-INF/struts-tags.tld | 11308 ++++++++++++++++
.../org/apache/struts2/default.properties | 146 +
.../org/apache/struts2/dispatcher/error.ftl | 123 +
.../struts2/interceptor/debugging/console.ftl | 14 +
.../interceptor/debugging/webconsole.css | 19 +
.../interceptor/debugging/webconsole.html | 21 +
.../interceptor/debugging/webconsole.js | 58 +
.../apache/struts2/interceptor/package.html | 1 +
.../org/apache/struts2/interceptor/wait.ftl | 11 +
.../resources/org/apache/struts2/package.html | 1 +
.../struts2/sitegraph/sitegraph-usage.txt | 7 +
.../apache/struts2/static/CommonFunctions.js | 97 +
.../org/apache/struts2/static/dojo/LICENSE | 195 +
.../org/apache/struts2/static/dojo/README | 175 +
.../org/apache/struts2/static/dojo/build.txt | 13 +
.../org/apache/struts2/static/dojo/dojo.js | 2521 ++++
.../static/dojo/dojo.js.uncompressed.js | 3476 +++++
.../apache/struts2/static/dojo/src/alg/Alg.js | 49 +
.../static/dojo/src/alg/__package__.js | 12 +
.../static/dojo/src/animation/Animation.js | 361 +
.../static/dojo/src/animation/Timer.js | 39 +
.../static/dojo/src/animation/__package__.js | 14 +
.../struts2/static/dojo/src/bootstrap1.js | 663 +
.../struts2/static/dojo/src/bootstrap2.js | 90 +
.../struts2/static/dojo/src/browser_debug.js | 156 +
.../static/dojo/src/collections/ArrayList.js | 101 +
.../static/dojo/src/collections/BinaryTree.js | 200 +
.../static/dojo/src/collections/ByteArray.js | 19 +
.../dojo/src/collections/Collections.js | 74 +
.../static/dojo/src/collections/Dictionary.js | 76 +
.../static/dojo/src/collections/Graph.js | 142 +
.../static/dojo/src/collections/List.js | 17 +
.../static/dojo/src/collections/Queue.js | 51 +
.../static/dojo/src/collections/Set.js | 75 +
.../static/dojo/src/collections/SkipList.js | 143 +
.../static/dojo/src/collections/SortedList.js | 141 +
.../static/dojo/src/collections/Stack.js | 51 +
.../dojo/src/collections/__package__.js | 22 +
.../apache/struts2/static/dojo/src/crypto.js | 15 +
.../static/dojo/src/crypto/Blowfish.js | 548 +
.../struts2/static/dojo/src/crypto/LICENSE | 11 +
.../struts2/static/dojo/src/crypto/MD5.js | 197 +
.../static/dojo/src/crypto/Rijndael.js | 21 +
.../struts2/static/dojo/src/crypto/SHA.js | 17 +
.../struts2/static/dojo/src/crypto/SHA1.js | 150 +
.../struts2/static/dojo/src/crypto/SHA256.js | 17 +
.../static/dojo/src/crypto/__package__.js | 17 +
.../apache/struts2/static/dojo/src/data.js | 15 +
.../static/dojo/src/data/__package__.js | 14 +
.../apache/struts2/static/dojo/src/date.js | 384 +
.../static/dojo/src/dnd/DragAndDrop.js | 158 +
.../static/dojo/src/dnd/HtmlDragAndDrop.js | 381 +
.../static/dojo/src/dnd/HtmlDragManager.js | 365 +
.../static/dojo/src/dnd/HtmlDragMove.js | 74 +
.../struts2/static/dojo/src/dnd/Sortable.js | 28 +
.../static/dojo/src/dnd/TreeDragAndDrop.js | 180 +
.../static/dojo/src/dnd/__package__.js | 15 +
.../org/apache/struts2/static/dojo/src/dom.js | 465 +
.../apache/struts2/static/dojo/src/event.js | 484 +
.../static/dojo/src/event/__package__.js | 15 +
.../struts2/static/dojo/src/event/browser.js | 266 +
.../struts2/static/dojo/src/event/topic.js | 90 +
.../apache/struts2/static/dojo/src/flash.js | 703 +
.../src/flash/flash6/DojoExternalInterface.as | 154 +
.../src/flash/flash8/DojoExternalInterface.as | 44 +
.../struts2/static/dojo/src/fx/__package__.js | 14 +
.../apache/struts2/static/dojo/src/fx/html.js | 565 +
.../apache/struts2/static/dojo/src/fx/svg.js | 100 +
.../static/dojo/src/graphics/Colorspace.js | 944 ++
.../static/dojo/src/graphics/__package__.js | 14 +
.../struts2/static/dojo/src/graphics/color.js | 414 +
.../static/dojo/src/graphics/htmlEffects.js | 16 +
.../static/dojo/src/hostenv_adobesvg.js | 571 +
.../static/dojo/src/hostenv_browser.js | 375 +
.../struts2/static/dojo/src/hostenv_jsc.js | 76 +
.../struts2/static/dojo/src/hostenv_rhino.js | 176 +
.../static/dojo/src/hostenv_spidermonkey.js | 80 +
.../struts2/static/dojo/src/hostenv_svg.js | 223 +
.../struts2/static/dojo/src/hostenv_wsh.js | 46 +
.../apache/struts2/static/dojo/src/html.js | 987 ++
.../struts2/static/dojo/src/iCalendar.js | 264 +
.../org/apache/struts2/static/dojo/src/io.js | 317 +
.../struts2/static/dojo/src/io/BrowserIO.js | 623 +
.../struts2/static/dojo/src/io/IframeIO.js | 219 +
.../struts2/static/dojo/src/io/RepubsubIO.js | 524 +
.../struts2/static/dojo/src/io/RhinoIO.js | 22 +
.../struts2/static/dojo/src/io/__package__.js | 16 +
.../struts2/static/dojo/src/io/cookie.js | 103 +
.../struts2/static/dojo/src/io/cookies.js | 14 +
.../apache/struts2/static/dojo/src/json.js | 126 +
.../apache/struts2/static/dojo/src/lang.js | 687 +
.../struts2/static/dojo/src/lang/Lang.js | 12 +
.../static/dojo/src/lang/__package__.js | 14 +
.../struts2/static/dojo/src/logging/Logger.js | 408 +
.../static/dojo/src/logging/__package__.js | 15 +
.../apache/struts2/static/dojo/src/math.js | 134 +
.../struts2/static/dojo/src/math/Math.js | 12 +
.../static/dojo/src/math/__package__.js | 18 +
.../struts2/static/dojo/src/math/curves.js | 222 +
.../struts2/static/dojo/src/math/matrix.js | 305 +
.../struts2/static/dojo/src/math/points.js | 47 +
.../apache/struts2/static/dojo/src/profile.js | 117 +
.../static/dojo/src/reflect/__package__.js | 14 +
.../static/dojo/src/reflect/reflection.js | 197 +
.../apache/struts2/static/dojo/src/regexp.js | 566 +
.../struts2/static/dojo/src/rpc/Deferred.js | 372 +
.../struts2/static/dojo/src/rpc/JotService.js | 40 +
.../static/dojo/src/rpc/JsonService.js | 97 +
.../struts2/static/dojo/src/rpc/RpcService.js | 114 +
.../static/dojo/src/rpc/__package__.js | 14 +
.../struts2/static/dojo/src/selection.js | 403 +
.../apache/struts2/static/dojo/src/storage.js | 72 +
.../static/dojo/src/storage/Storage.as | 51 +
.../static/dojo/src/storage/Storage.swf | Bin 0 -> 642 bytes
.../static/dojo/src/storage/__package__.js | 16 +
.../static/dojo/src/storage/browser.js | 102 +
.../static/dojo/src/storage/storage.sh | 3 +
.../apache/struts2/static/dojo/src/string.js | 318 +
.../struts2/static/dojo/src/string/Builder.js | 105 +
.../static/dojo/src/string/__package__.js | 17 +
.../apache/struts2/static/dojo/src/style.js | 540 +
.../org/apache/struts2/static/dojo/src/svg.js | 277 +
.../struts2/static/dojo/src/text/Builder.js | 16 +
.../struts2/static/dojo/src/text/String.js | 15 +
.../struts2/static/dojo/src/text/Text.js | 15 +
.../static/dojo/src/text/__package__.js | 17 +
.../static/dojo/src/text/textDirectory.js | 81 +
.../struts2/static/dojo/src/undo/Manager.js | 91 +
.../apache/struts2/static/dojo/src/uri/Uri.js | 108 +
.../static/dojo/src/uri/__package__.js | 14 +
.../struts2/static/dojo/src/validate.js | 781 ++
.../static/dojo/src/webui/DomWidget.js | 28 +
.../static/dojo/src/webui/HtmlWidget.js | 19 +
.../static/dojo/src/webui/SvgWidget.js | 19 +
.../struts2/static/dojo/src/webui/Widget.js | 21 +
.../static/dojo/src/webui/WidgetManager.js | 18 +
.../static/dojo/src/webui/__package__.js | 21 +
.../static/dojo/src/webui/widgets/Button.js | 17 +
.../static/dojo/src/webui/widgets/ComboBox.js | 19 +
.../dojo/src/webui/widgets/ContextMenu.js | 17 +
.../dojo/src/webui/widgets/DropdownButtons.js | 19 +
.../dojo/src/webui/widgets/HTMLButton.js | 17 +
.../dojo/src/webui/widgets/HTMLComboBox.js | 17 +
.../dojo/src/webui/widgets/HTMLContextMenu.js | 17 +
.../static/dojo/src/webui/widgets/HTMLMenu.js | 17 +
.../dojo/src/webui/widgets/HTMLMenuItem.js | 17 +
.../webui/widgets/HTMLResizableTextarea.js | 17 +
.../dojo/src/webui/widgets/InlineEditBox.js | 18 +
.../static/dojo/src/webui/widgets/Menu.js | 18 +
.../static/dojo/src/webui/widgets/MenuItem.js | 18 +
.../static/dojo/src/webui/widgets/Parse.js | 22 +
.../dojo/src/webui/widgets/SVGButton.js | 17 +
.../dojo/src/webui/widgets/SlideShow.js | 18 +
.../static/dojo/src/webui/widgets/Tabs.js | 18 +
.../dojo/src/webui/widgets/__package__.js | 14 +
.../static/dojo/src/widget/Accordion.js | 200 +
.../struts2/static/dojo/src/widget/Button.js | 23 +
.../struts2/static/dojo/src/widget/Button2.js | 55 +
.../struts2/static/dojo/src/widget/Chart.js | 170 +
.../static/dojo/src/widget/Checkbox.js | 28 +
.../dojo/src/widget/CiviCrmDatePicker.js | 119 +
.../static/dojo/src/widget/ColorPalette.js | 181 +
.../static/dojo/src/widget/ComboBox.js | 197 +
.../static/dojo/src/widget/Container.js | 12 +
.../static/dojo/src/widget/ContentPane.js | 16 +
.../static/dojo/src/widget/ContextMenu.js | 33 +
.../static/dojo/src/widget/DatePicker.js | 74 +
.../static/dojo/src/widget/DebugConsole.js | 22 +
.../struts2/static/dojo/src/widget/Dialog.js | 297 +
.../static/dojo/src/widget/DomWidget.js | 534 +
.../static/dojo/src/widget/DropdownButton.js | 29 +
.../struts2/static/dojo/src/widget/Editor.js | 619 +
.../static/dojo/src/widget/EditorTree.js | 499 +
.../dojo/src/widget/EditorTreeContextMenu.js | 136 +
.../dojo/src/widget/EditorTreeController.js | 742 +
.../static/dojo/src/widget/EditorTreeNode.js | 454 +
.../dojo/src/widget/EditorTreeSelector.js | 34 +
.../static/dojo/src/widget/FisheyeList.js | 742 +
.../static/dojo/src/widget/FloatingPane.js | 528 +
.../static/dojo/src/widget/HslColorPicker.js | 25 +
.../static/dojo/src/widget/HtmlWidget.js | 226 +
.../static/dojo/src/widget/InlineEditBox.js | 196 +
.../static/dojo/src/widget/LayoutPane.js | 17 +
.../static/dojo/src/widget/LinkPane.js | 17 +
.../struts2/static/dojo/src/widget/Manager.js | 279 +
.../struts2/static/dojo/src/widget/Menu.js | 59 +
.../struts2/static/dojo/src/widget/Menu2.js | 703 +
.../static/dojo/src/widget/MenuItem.js | 47 +
.../struts2/static/dojo/src/widget/Parse.js | 320 +
.../static/dojo/src/widget/PopUpButton.js | 192 +
.../dojo/src/widget/ResizableTextarea.js | 110 +
.../static/dojo/src/widget/ResizeHandle.js | 101 +
.../static/dojo/src/widget/RichText.js | 1041 ++
.../dojo/src/widget/SimpleDropdownButtons.js | 158 +
.../static/dojo/src/widget/SlideShow.js | 133 +
.../static/dojo/src/widget/SplitPane.js | 514 +
.../static/dojo/src/widget/SvgButton.js | 143 +
.../static/dojo/src/widget/SvgWidget.js | 92 +
.../struts2/static/dojo/src/widget/TabPane.js | 155 +
.../struts2/static/dojo/src/widget/Tabs.js | 279 +
.../struts2/static/dojo/src/widget/TaskBar.js | 32 +
.../dojo/src/widget/TemplatedContainer.js | 50 +
.../static/dojo/src/widget/TimePicker.js | 113 +
.../struts2/static/dojo/src/widget/Toggler.js | 40 +
.../struts2/static/dojo/src/widget/Toolbar.js | 960 ++
.../struts2/static/dojo/src/widget/Tooltip.js | 24 +
.../struts2/static/dojo/src/widget/Tree.js | 515 +
.../struts2/static/dojo/src/widget/Widget.js | 475 +
.../struts2/static/dojo/src/widget/Wizard.js | 209 +
.../static/dojo/src/widget/__package__.js | 20 +
.../static/dojo/src/widget/html/Button.js | 63 +
.../static/dojo/src/widget/html/Button2.js | 280 +
.../static/dojo/src/widget/html/Checkbox.js | 105 +
.../static/dojo/src/widget/html/ComboBox.js | 419 +
.../static/dojo/src/widget/html/Container.js | 46 +
.../dojo/src/widget/html/ContentPane.js | 127 +
.../dojo/src/widget/html/ContextMenu.js | 166 +
.../static/dojo/src/widget/html/DatePicker.js | 307 +
.../dojo/src/widget/html/DebugConsole.js | 32 +
.../dojo/src/widget/html/DropdownButton.js | 188 +
.../static/dojo/src/widget/html/LayoutPane.js | 418 +
.../static/dojo/src/widget/html/LinkPane.js | 55 +
.../static/dojo/src/widget/html/Menu.js | 51 +
.../static/dojo/src/widget/html/MenuItem.js | 60 +
.../static/dojo/src/widget/html/TaskBar.js | 74 +
.../static/dojo/src/widget/html/TimePicker.js | 248 +
.../static/dojo/src/widget/html/Tooltip.js | 108 +
.../static/dojo/src/widget/html/stabile.js | 208 +
.../static/dojo/src/widget/svg/Chart.js | 534 +
.../dojo/src/widget/svg/HslColorPicker.js | 139 +
.../src/widget/templates/AccordionPanel.css | 24 +
.../src/widget/templates/AccordionPanel.html | 35 +
.../src/widget/templates/HslColorPicker.svg | 30 +
.../widget/templates/HtmlButton2Template.css | 59 +
.../widget/templates/HtmlButton2Template.html | 6 +
.../widget/templates/HtmlButtonTemplate.css | 83 +
.../widget/templates/HtmlButtonTemplate.html | 3 +
.../templates/HtmlCiviCrmDatePicker.html | 12 +
.../src/widget/templates/HtmlComboBox.css | 39 +
.../src/widget/templates/HtmlComboBox.html | 34 +
.../templates/HtmlComboButton2Template.html | 18 +
.../templates/HtmlContextMenuTemplate.html | 3 +
.../src/widget/templates/HtmlDatePicker.css | 77 +
.../src/widget/templates/HtmlDatePicker.html | 110 +
.../dojo/src/widget/templates/HtmlDialog.html | 13 +
.../templates/HtmlDropDownButtonTemplate.html | 9 +
.../src/widget/templates/HtmlFisheyeList.css | 27 +
.../src/widget/templates/HtmlFloatingPane.css | 94 +
.../widget/templates/HtmlInlineEditBox.css | 24 +
.../widget/templates/HtmlInlineEditBox.html | 9 +
.../src/widget/templates/HtmlLayoutPane.css | 13 +
.../dojo/src/widget/templates/HtmlMenu2.css | 129 +
.../templates/HtmlMenuItemTemplate.html | 2 +
.../templates/HtmlResizableTextarea.css | 15 +
.../templates/HtmlResizableTextarea.html | 14 +
.../src/widget/templates/HtmlResizeHandle.css | 19 +
.../templates/HtmlSimpleDropdownButtons.css | 100 +
.../src/widget/templates/HtmlSlideShow.css | 9 +
.../src/widget/templates/HtmlSlideShow.html | 21 +
.../src/widget/templates/HtmlSplitPane.css | 45 +
.../dojo/src/widget/templates/HtmlTabPane.css | 69 +
.../dojo/src/widget/templates/HtmlTabs.css | 81 +
.../dojo/src/widget/templates/HtmlTaskBar.css | 27 +
.../templates/HtmlTaskBarItemTemplate.html | 2 +
.../src/widget/templates/HtmlTimePicker.css | 37 +
.../src/widget/templates/HtmlTimePicker.html | 99 +
.../dojo/src/widget/templates/HtmlToolbar.css | 54 +
.../widget/templates/HtmlTooltipTemplate.css | 10 +
.../widget/templates/HtmlTooltipTemplate.html | 2 +
.../static/dojo/src/widget/templates/Menu.css | 60 +
.../dojo/src/widget/templates/PopUpButton.css | 35 +
.../static/dojo/src/widget/templates/Tree.css | 29 +
.../dojo/src/widget/templates/Wizard.css | 72 +
.../dojo/src/widget/templates/Wizard.html | 11 +
.../dojo/src/widget/templates/buttons/-.gif | Bin 0 -> 58 bytes
.../widget/templates/buttons/backcolor.gif | Bin 0 -> 652 bytes
.../src/widget/templates/buttons/bold.gif | Bin 0 -> 74 bytes
.../src/widget/templates/buttons/cancel.gif | Bin 0 -> 618 bytes
.../src/widget/templates/buttons/copy.gif | Bin 0 -> 110 bytes
.../widget/templates/buttons/createlink.gif | Bin 0 -> 651 bytes
.../dojo/src/widget/templates/buttons/cut.gif | Bin 0 -> 91 bytes
.../src/widget/templates/buttons/delete.gif | Bin 0 -> 90 bytes
.../widget/templates/buttons/forecolor.gif | Bin 0 -> 612 bytes
.../widget/templates/buttons/hilitecolor.gif | Bin 0 -> 652 bytes
.../src/widget/templates/buttons/indent.gif | Bin 0 -> 87 bytes
.../buttons/inserthorizontalrule.gif | Bin 0 -> 70 bytes
.../widget/templates/buttons/insertimage.gif | Bin 0 -> 621 bytes
.../templates/buttons/insertorderedlist.gif | Bin 0 -> 82 bytes
.../widget/templates/buttons/inserttable.gif | Bin 0 -> 121 bytes
.../templates/buttons/insertunorderedlist.gif | Bin 0 -> 80 bytes
.../src/widget/templates/buttons/italic.gif | Bin 0 -> 77 bytes
.../templates/buttons/justifycenter.gif | Bin 0 -> 69 bytes
.../widget/templates/buttons/justifyfull.gif | Bin 0 -> 69 bytes
.../widget/templates/buttons/justifyleft.gif | Bin 0 -> 69 bytes
.../widget/templates/buttons/justifyright.gif | Bin 0 -> 68 bytes
.../templates/buttons/left_to_right.gif | Bin 0 -> 89 bytes
.../templates/buttons/list_bullet_indent.gif | Bin 0 -> 851 bytes
.../templates/buttons/list_bullet_outdent.gif | Bin 0 -> 852 bytes
.../templates/buttons/list_num_indent.gif | Bin 0 -> 855 bytes
.../templates/buttons/list_num_outdent.gif | Bin 0 -> 855 bytes
.../src/widget/templates/buttons/outdent.gif | Bin 0 -> 87 bytes
.../src/widget/templates/buttons/paste.gif | Bin 0 -> 139 bytes
.../src/widget/templates/buttons/redo.gif | Bin 0 -> 80 bytes
.../widget/templates/buttons/removeformat.gif | Bin 0 -> 118 bytes
.../templates/buttons/right_to_left.gif | Bin 0 -> 88 bytes
.../src/widget/templates/buttons/save.gif | Bin 0 -> 352 bytes
.../src/widget/templates/buttons/space.gif | Bin 0 -> 43 bytes
.../templates/buttons/strikethrough.gif | Bin 0 -> 78 bytes
.../widget/templates/buttons/subscript.gif | Bin 0 -> 78 bytes
.../widget/templates/buttons/superscript.gif | Bin 0 -> 77 bytes
.../widget/templates/buttons/underline.gif | Bin 0 -> 85 bytes
.../src/widget/templates/buttons/undo.gif | Bin 0 -> 81 bytes
.../src/widget/templates/buttons/wikiword.gif | Bin 0 -> 232 bytes
.../dojo/src/widget/templates/check_off.gif | Bin 0 -> 846 bytes
.../dojo/src/widget/templates/check_on.gif | Bin 0 -> 855 bytes
.../src/widget/templates/decrementMonth.gif | Bin 0 -> 166 bytes
.../src/widget/templates/decrementWeek.gif | Bin 0 -> 160 bytes
.../dojo/src/widget/templates/grabCorner.gif | Bin 0 -> 858 bytes
.../images/EditorTree/EditorTree.css | 30 +
.../templates/images/EditorTree/blank.gif | Bin 0 -> 47 bytes
.../templates/images/EditorTree/closed.gif | Bin 0 -> 126 bytes
.../templates/images/EditorTree/document.gif | Bin 0 -> 118 bytes
.../templates/images/EditorTree/minus.gif | Bin 0 -> 70 bytes
.../templates/images/EditorTree/open.gif | Bin 0 -> 142 bytes
.../templates/images/EditorTree/plus.gif | Bin 0 -> 75 bytes
.../images/EditorTree/treenode_blank.gif | Bin 0 -> 834 bytes
.../images/EditorTree/treenode_child.gif | Bin 0 -> 859 bytes
.../EditorTree/treenode_expand_minus.gif | Bin 0 -> 936 bytes
.../EditorTree/treenode_expand_plus.gif | Bin 0 -> 932 bytes
.../images/EditorTree/treenode_grid_c.gif | Bin 0 -> 840 bytes
.../images/EditorTree/treenode_grid_l.gif | Bin 0 -> 852 bytes
.../images/EditorTree/treenode_grid_p.gif | Bin 0 -> 844 bytes
.../images/EditorTree/treenode_grid_t.gif | Bin 0 -> 861 bytes
.../images/EditorTree/treenode_grid_v.gif | Bin 0 -> 857 bytes
.../images/EditorTree/treenode_grid_x.gif | Bin 0 -> 840 bytes
.../images/EditorTree/treenode_grid_y.gif | Bin 0 -> 851 bytes
.../images/EditorTree/treenode_grid_z.gif | Bin 0 -> 840 bytes
.../images/EditorTree/treenode_loading.gif | Bin 0 -> 680 bytes
.../src/widget/templates/images/blank.gif | Bin 0 -> 43 bytes
.../templates/images/combo_box_arrow.png | Bin 0 -> 305 bytes
.../images/dropdownButtonsArrow-disabled.gif | Bin 0 -> 52 bytes
.../templates/images/dropdownButtonsArrow.gif | Bin 0 -> 46 bytes
.../templates/images/floatingPaneClose.gif | Bin 0 -> 110 bytes
.../templates/images/floatingPaneMaximize.gif | Bin 0 -> 234 bytes
.../templates/images/floatingPaneMinimize.gif | Bin 0 -> 91 bytes
.../templates/images/floatingPaneRestore.gif | Bin 0 -> 379 bytes
.../dojo/src/widget/templates/images/hue.png | Bin 0 -> 365 bytes
.../dojo/src/widget/templates/images/no.gif | Bin 0 -> 338 bytes
.../dojo/src/widget/templates/images/no.svg | 51 +
.../images/pill-button-blue_benji-c.gif | Bin 0 -> 4433 bytes
.../images/pill-button-blue_benji-l.gif | Bin 0 -> 4349 bytes
.../images/pill-button-blue_benji-r.gif | Bin 0 -> 4361 bytes
.../images/pill-button-blue_benji_p_01.svg | 69 +
.../images/pill-button-gray_benji-c.gif | Bin 0 -> 1350 bytes
.../images/pill-button-gray_benji-l.gif | Bin 0 -> 850 bytes
.../images/pill-button-gray_benji-r.gif | Bin 0 -> 836 bytes
.../images/pill-button-gray_benji.svg | 69 +
.../images/pill-button-purple_benji-c.gif | Bin 0 -> 4415 bytes
.../images/pill-button-purple_benji-l.gif | Bin 0 -> 4397 bytes
.../images/pill-button-purple_benji-r.gif | Bin 0 -> 4361 bytes
.../images/pill-button-purple_benji_01.svg | 65 +
.../images/pill-button-seagreen_ben_01.svg | 65 +
.../images/pill-button-seagreen_benji-c.gif | Bin 0 -> 4454 bytes
.../images/pill-button-seagreen_benji-l.gif | Bin 0 -> 4136 bytes
.../images/pill-button-seagreen_benji-r.gif | Bin 0 -> 4104 bytes
.../src/widget/templates/images/shadowB.png | Bin 0 -> 271 bytes
.../src/widget/templates/images/shadowBL.png | Bin 0 -> 278 bytes
.../src/widget/templates/images/shadowBR.png | Bin 0 -> 261 bytes
.../src/widget/templates/images/shadowL.png | Bin 0 -> 181 bytes
.../src/widget/templates/images/shadowR.png | Bin 0 -> 182 bytes
.../src/widget/templates/images/shadowTR..png | Bin 0 -> 348 bytes
.../src/widget/templates/images/shadowUL.png | Bin 0 -> 260 bytes
.../src/widget/templates/images/shadowUR.png | Bin 0 -> 276 bytes
.../widget/templates/images/submenu_off.gif | Bin 0 -> 822 bytes
.../widget/templates/images/submenu_on.gif | Bin 0 -> 822 bytes
.../src/widget/templates/images/tab_left.gif | Bin 0 -> 609 bytes
.../widget/templates/images/tab_left_r.gif | Bin 0 -> 364 bytes
.../templates/images/tab_left_r_curr.gif | Bin 0 -> 341 bytes
.../src/widget/templates/images/tab_right.gif | Bin 0 -> 2574 bytes
.../widget/templates/images/tab_right_r.gif | Bin 0 -> 1353 bytes
.../templates/images/tab_right_r_curr.gif | Bin 0 -> 1228 bytes
.../widget/templates/images/titlebar-bg.jpg | Bin 0 -> 512 bytes
.../widget/templates/images/toolbar-bg.gif | Bin 0 -> 878 bytes
.../widget/templates/images/transparent.gif | Bin 0 -> 870 bytes
.../templates/images/treenode_blank.gif | Bin 0 -> 834 bytes
.../images/treenode_expand_minus.gif | Bin 0 -> 936 bytes
.../templates/images/treenode_expand_plus.gif | Bin 0 -> 932 bytes
.../templates/images/treenode_grid_c.gif | Bin 0 -> 840 bytes
.../templates/images/treenode_grid_l.gif | Bin 0 -> 852 bytes
.../templates/images/treenode_grid_p.gif | Bin 0 -> 844 bytes
.../templates/images/treenode_grid_t.gif | Bin 0 -> 861 bytes
.../templates/images/treenode_grid_v.gif | Bin 0 -> 857 bytes
.../templates/images/treenode_grid_x.gif | Bin 0 -> 840 bytes
.../templates/images/treenode_grid_y.gif | Bin 0 -> 851 bytes
.../templates/images/treenode_grid_z.gif | Bin 0 -> 840 bytes
.../widget/templates/images/treenode_node.gif | Bin 0 -> 957 bytes
.../widget/templates/images/verticalbar.gif | Bin 0 -> 158 bytes
.../templates/images/whiteDownArrow.gif | Bin 0 -> 46 bytes
.../src/widget/templates/incrementMonth.gif | Bin 0 -> 168 bytes
.../src/widget/templates/incrementWeek.gif | Bin 0 -> 159 bytes
.../struts2/static/dojo/src/xml/Parse.js | 171 +
.../static/dojo/src/xml/__package__.js | 17 +
.../struts2/static/dojo/src/xml/domUtil.js | 84 +
.../struts2/static/dojo/src/xml/htmlUtil.js | 121 +
.../struts2/static/dojo/src/xml/svgUtil.js | 32 +
.../apache/struts2/static/dojo/struts/Util.js | 51 +
.../struts2/static/dojo/struts/tooltip.gif | Bin 0 -> 324 bytes
.../static/dojo/struts/widgets/Bind.html | 1 +
.../static/dojo/struts/widgets/Bind.js | 202 +
.../dojo/struts/widgets/BindAnchor.html | 2 +
.../static/dojo/struts/widgets/BindAnchor.js | 75 +
.../dojo/struts/widgets/BindButton.html | 2 +
.../static/dojo/struts/widgets/BindButton.js | 69 +
.../static/dojo/struts/widgets/BindDiv.html | 2 +
.../static/dojo/struts/widgets/BindDiv.js | 157 +
.../dojo/struts/widgets/DateTimeUtil.js | 249 +
.../dojo/struts/widgets/DropDownDatePicker.js | 54 +
.../dojo/struts/widgets/DropDownTimePicker.js | 46 +
.../dojo/struts/widgets/DropdownContainer.js | 75 +
.../dojo/struts/widgets/DynArchCalendar.html | 4 +
.../dojo/struts/widgets/DynArchCalendar.js | 151 +
.../dojo/struts/widgets/ToggleBindDiv.js | 58 +
.../static/dojo/struts/widgets/__package__.js | 12 +
.../static/dojo/struts/widgets/dateIcon.gif | Bin 0 -> 392 bytes
.../dojo/struts/widgets/dropdowncontainer.css | 0
.../struts/widgets/dropdowncontainer.html | 18 +
.../static/dojo/struts/widgets/timeIcon.gif | Bin 0 -> 392 bytes
.../struts2/static/niftycorners/layout.js | 13 +
.../struts2/static/niftycorners/nifty.js | 174 +
.../static/niftycorners/niftyCorners.css | 21 +
.../static/niftycorners/niftyPrint.css | 2 +
.../static/niftycorners/niftylayout.css | 57 +
.../struts2/static/optiontransferselect.js | 163 +
.../org/apache/struts2/static/tabs.css | 79 +
.../org/apache/struts2/static/tree.css | 29 +
.../apache/struts2/static/validationClient.js | 37 +
.../apache/struts2/struts-messages.properties | 13 +
.../struts2/struts-messages_da.properties | 13 +
.../struts2/struts-messages_de.properties | 13 +
.../org/apache/struts2/util/package.html | 1 +
.../struts2/views/freemarker/package.html | 1 +
.../struts2/views/jsp/iterator/package.html | 1 +
.../apache/struts2/views/jsp/ui/package.html | 1 +
.../struts2/views/jsp/ui/table/package.html | 1 +
trunk/core/src/main/resources/overview.html | 6 +
trunk/core/src/main/resources/struts-2.0.dtd | 104 +
.../src/main/resources/struts-default.xml | 186 +
.../main/resources/struts-plugin-default.xml | 26 +
trunk/core/src/main/resources/struts.vm | 17 +
.../src/main/resources/template/ajax/a.ftl | 33 +
.../resources/template/ajax/controlheader.ftl | 11 +
.../src/main/resources/template/ajax/div.ftl | 25 +
.../resources/template/ajax/dojoRequire.js | 13 +
.../resources/template/ajax/form-close.ftl | 73 +
.../src/main/resources/template/ajax/form.ftl | 48 +
.../src/main/resources/template/ajax/head.ftl | 6 +
.../resources/template/ajax/submit-ajax.ftl | 41 +
.../main/resources/template/ajax/submit.ftl | 7 +
.../resources/template/ajax/tab-close.ftl | 7 +
.../src/main/resources/template/ajax/tab.ftl | 17 +
.../main/resources/template/ajax/textarea.ftl | 45 +
.../resources/template/ajax/theme.properties | 1 +
.../resources/template/ajax/tree-close.ftl | 1 +
.../src/main/resources/template/ajax/tree.ftl | 86 +
.../template/ajax/treenode-close.ftl | 1 +
.../template/ajax/treenode-include.ftl | 7 +
.../main/resources/template/ajax/treenode.ftl | 6 +
.../resources/template/ajax/validation.js | 26 +
.../template/archive/ajax/a-close.vm | 1 +
.../main/resources/template/archive/ajax/a.vm | 13 +
.../template/archive/ajax/div-close.vm | 1 +
.../resources/template/archive/ajax/div.vm | 15 +
.../template/archive/ajax/form-close.vm | 2 +
.../resources/template/archive/ajax/form.vm | 19 +
.../resources/template/archive/ajax/submit.vm | 13 +
.../template/archive/ajax/tab-close.vm | 7 +
.../resources/template/archive/ajax/tab.vm | 17 +
.../template/archive/simple/checkbox.vm | 10 +
.../template/archive/simple/checkboxlist.vm | 25 +
.../template/archive/simple/combobox.vm | 23 +
.../template/archive/simple/debug.vm | 65 +
.../template/archive/simple/doubleselect.vm | 88 +
.../template/archive/simple/empty.vm | 0
.../resources/template/archive/simple/file.vm | 12 +
.../template/archive/simple/form-close.vm | 1 +
.../resources/template/archive/simple/form.vm | 12 +
.../template/archive/simple/hidden.vm | 8 +
.../template/archive/simple/label.vm | 6 +
.../template/archive/simple/password.vm | 14 +
.../template/archive/simple/radiomap.vm | 35 +
.../archive/simple/scripting-events.vm | 14 +
.../template/archive/simple/select.vm | 43 +
.../template/archive/simple/submit.vm | 7 +
.../template/archive/simple/table.vm | 81 +
.../resources/template/archive/simple/text.vm | 14 +
.../template/archive/simple/textarea.vm | 13 +
.../template/archive/simple/token.vm | 2 +
.../template/archive/xhtml/checkbox.vm | 19 +
.../template/archive/xhtml/checkboxlist.vm | 3 +
.../template/archive/xhtml/combobox.vm | 1 +
.../template/archive/xhtml/controlfooter.vm | 2 +
.../template/archive/xhtml/controlheader.vm | 27 +
.../resources/template/archive/xhtml/debug.vm | 1 +
.../template/archive/xhtml/doubleselect.vm | 1 +
.../resources/template/archive/xhtml/empty.vm | 0
.../resources/template/archive/xhtml/file.vm | 1 +
.../template/archive/xhtml/form-close.vm | 2 +
.../resources/template/archive/xhtml/form.vm | 8 +
.../template/archive/xhtml/hidden.vm | 1 +
.../resources/template/archive/xhtml/label.vm | 1 +
.../template/archive/xhtml/password.vm | 1 +
.../template/archive/xhtml/radiomap.vm | 1 +
.../template/archive/xhtml/select.vm | 1 +
.../template/archive/xhtml/submit.vm | 3 +
.../resources/template/archive/xhtml/table.vm | 1 +
.../resources/template/archive/xhtml/text.vm | 1 +
.../template/archive/xhtml/textarea.vm | 2 +
.../resources/template/archive/xhtml/token.vm | 1 +
.../resources/template/css_xhtml/checkbox.ftl | 58 +
.../template/css_xhtml/checkboxlist.ftl | 4 +
.../resources/template/css_xhtml/combobox.ftl | 4 +
.../template/css_xhtml/control-close.ftl | 0
.../resources/template/css_xhtml/control.ftl | 0
.../template/css_xhtml/controlfooter.ftl | 8 +
.../template/css_xhtml/controlheader-core.ftl | 50 +
.../template/css_xhtml/controlheader.ftl | 8 +
.../template/css_xhtml/datepicker.ftl | 4 +
.../resources/template/css_xhtml/debug.ftl | 1 +
.../template/css_xhtml/doubleselect.ftl | 4 +
.../resources/template/css_xhtml/file.ftl | 4 +
.../template/css_xhtml/form-close.ftl | 3 +
.../template/css_xhtml/form-validate.ftl | 8 +
.../resources/template/css_xhtml/form.ftl | 3 +
.../resources/template/css_xhtml/head.ftl | 2 +
.../resources/template/css_xhtml/label.ftl | 25 +
.../css_xhtml/optiontransferselect.ftl | 4 +
.../resources/template/css_xhtml/password.ftl | 4 +
.../resources/template/css_xhtml/radiomap.ftl | 5 +
.../resources/template/css_xhtml/reset.ftl | 19 +
.../resources/template/css_xhtml/select.ftl | 4 +
.../resources/template/css_xhtml/styles.css | 11 +
.../resources/template/css_xhtml/submit.ftl | 18 +
.../resources/template/css_xhtml/text.ftl | 4 +
.../resources/template/css_xhtml/textarea.ftl | 4 +
.../template/css_xhtml/theme.properties | 1 +
.../template/css_xhtml/updownselect.ftl | 4 +
.../template/css_xhtml/validation.js | 69 +
.../resources/template/simple/a-close.ftl | 1 +
.../src/main/resources/template/simple/a.ftl | 19 +
.../resources/template/simple/actionerror.ftl | 7 +
.../template/simple/actionmessage.ftl | 7 +
.../resources/template/simple/checkbox.ftl | 29 +
.../template/simple/checkboxlist.ftl | 33 +
.../resources/template/simple/combobox.ftl | 50 +
.../template/simple/common-attributes.ftl | 3 +
.../template/simple/controlfooter.ftl | 0
.../template/simple/controlheader.ftl | 0
.../resources/template/simple/datepicker.ftl | 58 +
.../main/resources/template/simple/debug.ftl | 59 +
.../resources/template/simple/div-close.ftl | 1 +
.../main/resources/template/simple/div.ftl | 10 +
.../resources/template/simple/dojoRequire.js | 2 +
.../template/simple/doubleselect.ftl | 108 +
.../main/resources/template/simple/empty.ftl | 0
.../resources/template/simple/fielderror.ftl | 39 +
.../main/resources/template/simple/file.ftl | 32 +
.../resources/template/simple/form-close.ftl | 74 +
.../main/resources/template/simple/form.ftl | 47 +
.../main/resources/template/simple/head.ftl | 13 +
.../main/resources/template/simple/hidden.ftl | 15 +
.../main/resources/template/simple/label.ftl | 22 +
.../resources/template/simple/optgroup.ftl | 27 +
.../template/simple/optiontransferselect.ftl | 286 +
.../resources/template/simple/password.ftl | 35 +
.../resources/template/simple/radiomap.ftl | 41 +
.../main/resources/template/simple/reset.ftl | 38 +
.../template/simple/scripting-events.ftl | 42 +
.../main/resources/template/simple/select.ftl | 61 +
.../main/resources/template/simple/submit.ftl | 54 +
.../resources/template/simple/tab-close.ftl | 7 +
.../main/resources/template/simple/tab.ftl | 7 +
.../template/simple/tabbedpanel-close.ftl | 14 +
.../resources/template/simple/tabbedpanel.ftl | 1 +
.../main/resources/template/simple/table.ftl | 54 +
.../main/resources/template/simple/text.ftl | 35 +
.../resources/template/simple/textarea.ftl | 35 +
.../resources/template/simple/timepicker.ftl | 33 +
.../main/resources/template/simple/token.ftl | 2 +
.../template/simple/updownselect.ftl | 35 +
.../resources/template/xhtml/checkbox.ftl | 102 +
.../resources/template/xhtml/checkboxlist.ftl | 4 +
.../resources/template/xhtml/combobox.ftl | 4 +
.../template/xhtml/control-close.ftl | 1 +
.../main/resources/template/xhtml/control.ftl | 4 +
.../template/xhtml/controlfooter.ftl | 3 +
.../template/xhtml/controlheader-core.ftl | 56 +
.../template/xhtml/controlheader.ftl | 6 +
.../resources/template/xhtml/datepicker.ftl | 3 +
.../main/resources/template/xhtml/debug.ftl | 1 +
.../resources/template/xhtml/doubleselect.ftl | 4 +
.../main/resources/template/xhtml/file.ftl | 3 +
.../template/xhtml/form-close-validate.ftl | 99 +
.../resources/template/xhtml/form-close.ftl | 3 +
.../template/xhtml/form-validate.ftl | 8 +
.../main/resources/template/xhtml/form.ftl | 3 +
.../main/resources/template/xhtml/head.ftl | 2 +
.../main/resources/template/xhtml/label.ftl | 3 +
.../template/xhtml/optiontransferselect.ftl | 3 +
.../resources/template/xhtml/password.ftl | 3 +
.../resources/template/xhtml/radiomap.ftl | 4 +
.../main/resources/template/xhtml/reset.ftl | 9 +
.../main/resources/template/xhtml/select.ftl | 3 +
.../main/resources/template/xhtml/styles.css | 8 +
.../main/resources/template/xhtml/submit.ftl | 9 +
.../main/resources/template/xhtml/text.ftl | 3 +
.../resources/template/xhtml/textarea.ftl | 3 +
.../resources/template/xhtml/theme.properties | 1 +
.../resources/template/xhtml/timepicker.ftl | 3 +
.../main/resources/template/xhtml/tooltip.ftl | 24 +
.../resources/template/xhtml/updownselect.ftl | 3 +
.../resources/template/xhtml/validation.js | 74 +
trunk/core/src/main/xdt/Readme-tagdoclet.txt | 33 +
trunk/core/src/main/xdt/tagdoc-toc.xdt | 40 +
trunk/core/src/main/xdt/tagdoc.xdt | 78 +
trunk/core/src/main/xdt/tags_tld.xdt | 264 +
.../struts2/ExecutionCountTestAction.java | 50 +
.../org/apache/struts2/RequestUtilsTest.java | 81 +
.../struts2/ServletActionContextTest.java | 73 +
.../java/org/apache/struts2/TestAction.java | 139 +
.../apache/struts2/TestActionTagResult.java | 40 +
.../struts2/TestConfigurationProvider.java | 151 +
.../java/org/apache/struts2/TestResult.java | 97 +
.../struts2/components/ComponentTest.java | 507 +
.../struts2/components/FormButtonTest.java | 121 +
.../apache/struts2/components/FormTest.java | 41 +
.../struts2/components/PropertyTest.java | 143 +
.../apache/struts2/components/UIBeanTest.java | 64 +
.../struts2/components/UIComponentTest.java | 540 +
.../template/BaseTemplateEngineTest.java | 83 +
.../apache/struts2/config/SettingsTest.java | 88 +
.../apache/struts2/config/TestSettings.java | 50 +
.../struts2/dispatcher/DispatcherTest.java | 80 +
.../dispatcher/FilterDispatcherTest.java | 332 +
.../dispatcher/HttpHeaderResultTest.java | 103 +
.../struts2/dispatcher/NullActionMapper.java | 48 +
.../dispatcher/PlainTextResultTest.java | 154 +
.../ServletActionRedirectResultTest.java | 159 +
...ervletDispatchedTestAssertInterceptor.java | 55 +
.../ServletDispatcherResultTest.java | 103 +
.../dispatcher/ServletRedirectResultTest.java | 124 +
.../struts2/dispatcher/SessionMapTest.java | 189 +
.../struts2/dispatcher/StreamResultTest.java | 219 +
.../dispatcher/StrutsResultSupportTest.java | 120 +
.../dispatcher/VelocityResultTest.java | 144 +
.../mapper/DefaultActionMapperTest.java | 398 +
.../mapper/RestfulActionMapperTest.java | 115 +
.../org/apache/struts2/impl/MessagesTest.java | 31 +
.../struts2/impl/RequestContextTest.java | 72 +
.../CreateSessionInterceptorTest.java | 48 +
.../ExecuteAndWaitDelayAction.java | 33 +
.../ExecuteAndWaitInterceptorTest.java | 223 +
.../FileUploadInterceptorTest.java | 251 +
.../MessageStoreInterceptorTest.java | 244 +
.../ServletConfigInterceptorTest.java | 228 +
.../StrutsConversionErrorInterceptorTest.java | 95 +
.../interceptor/TokenInterceptorTest.java | 137 +
.../TokenSessionStoreInterceptorTest.java | 47 +
.../portlet/PortletApplicationMapTest.java | 166 +
.../portlet/PortletRequestMapTest.java | 137 +
.../portlet/PortletSessionMapTest.java | 154 +
.../context/PortletActionContextTest.java | 178 +
.../context/PreparatorServletTest.java | 64 +
.../ServletContextHolderListenerTest.java | 43 +
.../dispatcher/Jsr168DispatcherTest.java | 296 +
.../portlet/result/PortletResultTest.java | 245 +
.../portlet/util/PortletUrlHelperTest.java | 156 +
.../struts2/portlet/util/StrutsUtilTest.java | 240 +
.../spring/StrutsSpringObjectFactoryTest.java | 65 +
.../org/apache/struts2/util/CounterTest.java | 51 +
.../util/InvocationSessionStoreTest.java | 88 +
.../apache/struts2/util/PrefixTrieTest.java | 38 +
.../struts2/util/StrutsTypeConverterTest.java | 107 +
.../apache/struts2/util/TokenHelperTest.java | 71 +
.../views/TemplateEngineManagerTest.java | 74 +
.../freemarker/FreemarkerManagerTest.java | 38 +
.../views/freemarker/FreemarkerTest.java | 90 +
.../struts2/views/freemarker/TestAction.java | 54 +
.../struts2/views/freemarker/TestBean.java | 57 +
.../struts2/views/jsp/AbstractTagTest.java | 131 +
.../struts2/views/jsp/AbstractUITagTest.java | 358 +
.../struts2/views/jsp/ActionTagTest.java | 257 +
.../struts2/views/jsp/AnchorTagTest.java | 78 +
.../views/jsp/AppendIteratorTagTest.java | 178 +
.../apache/struts2/views/jsp/BeanTagTest.java | 49 +
.../struts2/views/jsp/ElseIfTagTest.java | 114 +
.../apache/struts2/views/jsp/ElseTagTest.java | 123 +
.../apache/struts2/views/jsp/IfTagTest.java | 350 +
.../struts2/views/jsp/IncludeTagTest.java | 118 +
.../views/jsp/IteratorGeneratorTagTest.java | 207 +
.../struts2/views/jsp/IteratorTagTest.java | 423 +
.../views/jsp/MergeIteratorTagTest.java | 180 +
.../struts2/views/jsp/PortletUrlTagTest.java | 360 +
.../struts2/views/jsp/PropertyTagTest.java | 302 +
.../apache/struts2/views/jsp/PushTagTest.java | 46 +
.../apache/struts2/views/jsp/SetTagTest.java | 120 +
.../views/jsp/SortIteratorTagTest.java | 214 +
.../views/jsp/StrutsMockBodyContent.java | 159 +
.../jsp/StrutsMockHttpServletRequest.java | 206 +
.../jsp/StrutsMockHttpServletResponse.java | 62 +
.../views/jsp/StrutsMockHttpSession.java | 66 +
.../views/jsp/StrutsMockJspWriter.java | 167 +
.../views/jsp/StrutsMockPageContext.java | 79 +
.../views/jsp/StrutsMockServletContext.java | 158 +
.../views/jsp/SubsetIteratorTagTest.java | 276 +
.../apache/struts2/views/jsp/TextTagTest.java | 278 +
.../apache/struts2/views/jsp/URLTagTest.java | 477 +
.../views/jsp/ui/ActionErrorTagTest.java | 93 +
.../views/jsp/ui/ActionMessageTagTest.java | 96 +
.../struts2/views/jsp/ui/AnchorTest.java | 50 +
.../apache/struts2/views/jsp/ui/Category.java | 102 +
.../views/jsp/ui/CheckboxListTest.java | 182 +
.../struts2/views/jsp/ui/CheckboxTest.java | 158 +
.../struts2/views/jsp/ui/ComboBoxTest.java | 139 +
.../struts2/views/jsp/ui/ComponentTest.java | 113 +
.../views/jsp/ui/DatePickerTagTest.java | 98 +
.../struts2/views/jsp/ui/DateTagTest.java | 248 +
.../apache/struts2/views/jsp/ui/DivTest.java | 68 +
.../views/jsp/ui/DoubleSelectTest.java | 259 +
.../views/jsp/ui/FieldErrorTagTest.java | 242 +
.../apache/struts2/views/jsp/ui/FileTest.java | 83 +
.../struts2/views/jsp/ui/FormTagTest.java | 545 +
.../struts2/views/jsp/ui/HeadTagTest.java | 102 +
.../struts2/views/jsp/ui/HiddenTest.java | 80 +
.../struts2/views/jsp/ui/JspTemplateTest.java | 50 +
.../struts2/views/jsp/ui/LabelTest.java | 114 +
.../apache/struts2/views/jsp/ui/MockTag.java | 125 +
.../struts2/views/jsp/ui/OptGroupTest.java | 120 +
.../jsp/ui/OptionTransferSelectTagTest.java | 520 +
.../struts2/views/jsp/ui/PasswordTest.java | 59 +
.../struts2/views/jsp/ui/RadioTest.java | 130 +
.../struts2/views/jsp/ui/ResetTest.java | 132 +
.../struts2/views/jsp/ui/SelectTest.java | 301 +
.../views/jsp/ui/StrutsBodyContent.java | 170 +
.../struts2/views/jsp/ui/SubmitAjaxTest.java | 44 +
.../struts2/views/jsp/ui/SubmitTest.java | 246 +
.../struts2/views/jsp/ui/TestAction1.java | 29 +
.../struts2/views/jsp/ui/TextareaTest.java | 88 +
.../struts2/views/jsp/ui/TextfieldTest.java | 134 +
.../struts2/views/jsp/ui/TokenTagTest.java | 95 +
.../struts2/views/jsp/ui/TooltipTest.java | 250 +
.../apache/struts2/views/jsp/ui/TreeTest.java | 133 +
.../views/jsp/ui/UpDownSelectTagTest.java | 272 +
.../org/apache/struts2/views/jsp/ui/User.java | 39 +
.../struts2/views/util/ContextUtilTest.java | 132 +
.../struts2/views/util/ResourceUtilTest.java | 54 +
.../struts2/views/util/TextUtilTest.java | 68 +
.../struts2/views/util/UrlHelperTest.java | 329 +
.../struts2/views/xslt/XSLTResultTest.java | 189 +
.../src/test/resources/XSLTResultTest.xsl | 9 +
.../src/test/resources/XSLTResultTest2.xsl | 13 +
.../src/test/resources/XSLTResultTest3.xsl | 19 +
.../core/src/test/resources/log4j.properties | 7 +
.../apache/struts2/TestAction-validation.xml | 13 +
.../org/apache/struts2/TestAction.properties | 5 +
.../components/template/dummy.properties | 0
.../theme1/themeThroughClassPath.properties | 1 +
.../theme1/themeThroughFileSystem.properties | 1 +
.../struts2/components/tempo.properties | 0
.../apache/struts2/dispatcher/someJspFile.jsp | 12 +
.../FileUploadInterceptor.properties | 3 +
.../org/apache/struts2/othertest.properties | 1 +
...ngObjectFactoryTest-applicationContext.xml | 6 +
.../struts2/views/jsp/ui/Checkbox-1.txt | 9 +
.../struts2/views/jsp/ui/Checkbox-2.txt | 9 +
.../struts2/views/jsp/ui/Checkbox-3.txt | 16 +
.../struts2/views/jsp/ui/Checkbox-4.txt | 11 +
.../struts2/views/jsp/ui/Checkbox-5.txt | 9 +
.../struts2/views/jsp/ui/CheckboxList-1.txt | 9 +
.../struts2/views/jsp/ui/CheckboxList-2.txt | 11 +
.../struts2/views/jsp/ui/CheckboxList-3.txt | 11 +
.../struts2/views/jsp/ui/CheckboxList-4.txt | 9 +
.../struts2/views/jsp/ui/ComboBox-1.txt | 16 +
.../struts2/views/jsp/ui/ComboBox-2.txt | 25 +
.../struts2/views/jsp/ui/ComboBox-3.txt | 25 +
.../struts2/views/jsp/ui/Component-1.txt | 0
.../struts2/views/jsp/ui/Component-2.txt | 8 +
.../struts2/views/jsp/ui/Component-3.txt | 8 +
.../struts2/views/jsp/ui/Component-param.txt | 8 +
.../views/jsp/ui/DatePickerTagTest-1.txt | 15 +
.../views/jsp/ui/DatePickerTagTest-2.txt | 16 +
.../struts2/views/jsp/ui/DoubleSelect-1.txt | 41 +
.../struts2/views/jsp/ui/DoubleSelect-2.txt | 45 +
.../apache/struts2/views/jsp/ui/File-1.txt | 4 +
.../apache/struts2/views/jsp/ui/Formtag-1.txt | 4 +
.../struts2/views/jsp/ui/Formtag-10.txt | 4 +
.../struts2/views/jsp/ui/Formtag-11.txt | 30 +
.../apache/struts2/views/jsp/ui/Formtag-2.txt | 40 +
.../apache/struts2/views/jsp/ui/Formtag-3.txt | 4 +
.../apache/struts2/views/jsp/ui/Formtag-4.txt | 4 +
.../apache/struts2/views/jsp/ui/Formtag-5.txt | 4 +
.../apache/struts2/views/jsp/ui/Formtag-6.txt | 29 +
.../apache/struts2/views/jsp/ui/Formtag-7.txt | 4 +
.../apache/struts2/views/jsp/ui/Formtag-8.txt | 4 +
.../apache/struts2/views/jsp/ui/Formtag-9.txt | 4 +
.../struts2/views/jsp/ui/HeadTagTest-1.txt | 17 +
.../struts2/views/jsp/ui/HeadTagTest-2.txt | 18 +
.../struts2/views/jsp/ui/HeadTagTest-3.txt | 18 +
.../struts2/views/jsp/ui/HeadTagTest-4.txt | 17 +
.../apache/struts2/views/jsp/ui/Hidden-1.txt | 1 +
.../apache/struts2/views/jsp/ui/Label-1.txt | 4 +
.../apache/struts2/views/jsp/ui/Label-2.txt | 4 +
.../apache/struts2/views/jsp/ui/Label-3.txt | 6 +
.../struts2/views/jsp/ui/OptGroup-1.txt | 40 +
.../struts2/views/jsp/ui/OptGroup-2.txt | 41 +
.../struts2/views/jsp/ui/OptGroup-3.txt | 42 +
.../struts2/views/jsp/ui/Password-1.txt | 4 +
.../apache/struts2/views/jsp/ui/Radio-1.txt | 7 +
.../apache/struts2/views/jsp/ui/Radio-2.txt | 7 +
.../apache/struts2/views/jsp/ui/Radio-3.txt | 7 +
.../apache/struts2/views/jsp/ui/Reset-1.txt | 3 +
.../apache/struts2/views/jsp/ui/Reset-2.txt | 3 +
.../apache/struts2/views/jsp/ui/Reset-3.txt | 3 +
.../apache/struts2/views/jsp/ui/Reset-4.txt | 3 +
.../apache/struts2/views/jsp/ui/Select-1.txt | 9 +
.../apache/struts2/views/jsp/ui/Select-2.txt | 8 +
.../apache/struts2/views/jsp/ui/Select-3.txt | 8 +
.../apache/struts2/views/jsp/ui/Select-4.txt | 5 +
.../apache/struts2/views/jsp/ui/Select-5.txt | 8 +
.../apache/struts2/views/jsp/ui/Select-6.txt | 8 +
.../apache/struts2/views/jsp/ui/Select-7.txt | 9 +
.../apache/struts2/views/jsp/ui/Select-8.txt | 10 +
.../apache/struts2/views/jsp/ui/Submit-1.txt | 3 +
.../apache/struts2/views/jsp/ui/Submit-2.txt | 3 +
.../apache/struts2/views/jsp/ui/Submit-3.txt | 3 +
.../apache/struts2/views/jsp/ui/Submit-4.txt | 3 +
.../apache/struts2/views/jsp/ui/Submit-5.txt | 3 +
.../apache/struts2/views/jsp/ui/Submit-6.txt | 3 +
.../views/jsp/ui/TestAction1.properties | 1 +
.../views/jsp/ui/TestAction1_de.properties | 1 +
.../views/jsp/ui/TestAction1_fr.properties | 1 +
.../struts2/views/jsp/ui/Textarea-1.txt | 4 +
.../struts2/views/jsp/ui/Textfield-1.txt | 4 +
.../struts2/views/jsp/ui/Textfield-2.txt | 7 +
.../struts2/views/jsp/ui/Textfield-3.txt | 4 +
.../struts2/views/jsp/ui/User-validation.xml | 8 +
.../struts2/views/jsp/ui/User.properties | 1 +
.../struts2/views/jsp/ui/actionerror-1.txt | 0
.../struts2/views/jsp/ui/actionerror-2.txt | 5 +
.../struts2/views/jsp/ui/actionmessage-1.txt | 0
.../struts2/views/jsp/ui/actionmessage-2.txt | 5 +
.../org/apache/struts2/views/jsp/ui/div-1.txt | 12 +
.../struts2/views/jsp/ui/fielderror-1.txt | 5 +
.../struts2/views/jsp/ui/fielderror-2.txt | 0
.../struts2/views/jsp/ui/fielderror-3.txt | 4 +
.../struts2/views/jsp/ui/fielderror-4.txt | 4 +
.../struts2/views/jsp/ui/fielderror-5.txt | 3 +
.../apache/struts2/views/jsp/ui/href-1.txt | 1 +
.../views/jsp/ui/optiontransferselect-1.txt | 49 +
.../views/jsp/ui/optiontransferselect-2.txt | 50 +
.../views/jsp/ui/optiontransferselect-3.txt | 49 +
.../views/jsp/ui/optiontransferselect-4.txt | 51 +
.../views/jsp/ui/optiontransferselect-5.txt | 49 +
.../views/jsp/ui/optiontransferselect-6.txt | 50 +
.../views/jsp/ui/optiontransferselect-7.txt | 45 +
.../struts2/views/jsp/ui/submit-ajax-1.txt | 1 +
.../apache/struts2/views/jsp/ui/tooltip-1.txt | 22 +
.../apache/struts2/views/jsp/ui/tooltip-2.txt | 19 +
.../apache/struts2/views/jsp/ui/tooltip-3.txt | 20 +
.../apache/struts2/views/jsp/ui/tree-1.txt | 42 +
.../apache/struts2/views/jsp/ui/tree-2.txt | 64 +
.../views/jsp/ui/updownselecttag-1.txt | 18 +
.../views/jsp/ui/updownselecttag-10.txt | 18 +
.../views/jsp/ui/updownselecttag-11.txt | 18 +
.../views/jsp/ui/updownselecttag-2.txt | 17 +
.../views/jsp/ui/updownselecttag-3.txt | 19 +
.../views/jsp/ui/updownselecttag-4.txt | 18 +
.../views/jsp/ui/updownselecttag-5.txt | 18 +
.../views/jsp/ui/updownselecttag-6.txt | 17 +
.../views/jsp/ui/updownselecttag-7.txt | 17 +
.../views/jsp/ui/updownselecttag-8.txt | 17 +
.../views/jsp/ui/updownselecttag-9.txt | 18 +
.../core/src/test/resources/struts.properties | 18 +
trunk/core/src/test/resources/struts.xml | 36 +
.../resources/template/test/Component.ftl | 8 +
.../test/resources/template/test/checkbox.jsp | 11 +
trunk/core/src/test/resources/test.properties | 1 +
.../test/resources/testmessages.properties | 2 +
.../test/resources/testmessages2.properties | 1 +
trunk/core/src/test/resources/validators.xml | 15 +
trunk/docs/tags/ActionComponent.html | 136 +
trunk/docs/tags/ActionError.html | 622 +
trunk/docs/tags/ActionMessage.html | 622 +
trunk/docs/tags/Anchor.html | 748 +
trunk/docs/tags/AppendIterator.html | 64 +
trunk/docs/tags/Bean.html | 82 +
trunk/docs/tags/Checkbox.html | 640 +
trunk/docs/tags/CheckboxList.html | 676 +
trunk/docs/tags/ComboBox.html | 802 ++
trunk/docs/tags/Date.html | 118 +
trunk/docs/tags/DatePicker.html | 766 ++
trunk/docs/tags/Debug.html | 604 +
trunk/docs/tags/Div.html | 784 ++
trunk/docs/tags/DoubleSelect.html | 1324 ++
trunk/docs/tags/Else.html | 64 +
trunk/docs/tags/ElseIf.html | 82 +
trunk/docs/tags/FieldError.html | 622 +
trunk/docs/tags/File.html | 658 +
trunk/docs/tags/Form.html | 820 ++
trunk/docs/tags/GenericUIBean.html | 622 +
trunk/docs/tags/Head.html | 658 +
trunk/docs/tags/Hidden.html | 622 +
trunk/docs/tags/I18n.html | 82 +
trunk/docs/tags/If.html | 82 +
trunk/docs/tags/Include.html | 82 +
trunk/docs/tags/IteratorComponent.html | 100 +
trunk/docs/tags/Label.html | 640 +
trunk/docs/tags/MergeIterator.html | 64 +
trunk/docs/tags/OptGroup.html | 154 +
trunk/docs/tags/OptionTransferSelect.html | 1576 +++
trunk/docs/tags/Panel.html | 838 ++
trunk/docs/tags/Param.html | 100 +
trunk/docs/tags/Password.html | 712 +
trunk/docs/tags/Property.html | 118 +
trunk/docs/tags/Push.html | 82 +
trunk/docs/tags/Radio.html | 676 +
trunk/docs/tags/Reset.html | 694 +
trunk/docs/tags/RichTextEditor.html | 1630 +++
trunk/docs/tags/Select.html | 766 ++
trunk/docs/tags/Set.html | 118 +
trunk/docs/tags/Submit.html | 802 ++
trunk/docs/tags/TabbedPanel.html | 640 +
trunk/docs/tags/Text.html | 82 +
trunk/docs/tags/TextArea.html | 694 +
trunk/docs/tags/TextField.html | 694 +
trunk/docs/tags/Token.html | 622 +
trunk/docs/tags/Tree.html | 1054 ++
trunk/docs/tags/TreeNode.html | 640 +
trunk/docs/tags/URL.html | 280 +
trunk/docs/tags/UpDownSelect.html | 874 ++
trunk/docs/tags/WebTable.html | 694 +
trunk/docs/tags/index.html | 567 +
trunk/plugins/config-browser/pom.xml | 22 +
.../config_browser/ActionNamesAction.java | 87 +
.../config_browser/ConfigurationHelper.java | 65 +
.../config_browser/ListValidatorsAction.java | 89 +
.../config_browser/ShowConfigAction.java | 109 +
.../config_browser/ShowValidatorAction.java | 177 +
.../resources/config-browser/actionNames.ftl | 22 +
.../config-browser/config-styles.css | 792 ++
.../main/resources/config-browser/error.ftl | 6 +
.../resources/config-browser/page-footer.ftl | 16 +
.../resources/config-browser/page-header.ftl | 44 +
.../resources/config-browser/showConfig.ftl | 116 +
.../config-browser/showValidators.ftl | 17 +
.../resources/config-browser/simple-error.ftl | 2 +
.../config-browser/tigris-macros.ftl | 108 +
.../config-browser/validatorDetails.ftl | 19 +
.../src/main/resources/struts-plugin.xml | 43 +
trunk/plugins/jasperreports/pom.xml | 23 +
.../views/jasperreports/CompileReport.java | 47 +
.../jasperreports/JasperReportConstants.java | 51 +
.../jasperreports/JasperReportsResult.java | 351 +
.../jasperreports/ValueStackDataSource.java | 134 +
.../jasperreports/ValueStackShadowMap.java | 90 +
.../struts2/views/jasperreports/package.html | 1 +
.../src/main/resources/struts-plugin.xml | 15 +
trunk/plugins/jfreechart/pom.xml | 49 +
.../struts2/dispatcher/ChartResult.java | 110 +
.../src/main/resources/struts-plugin.xml | 18 +
.../struts2/dispatcher/ChartResultTest.java | 114 +
trunk/plugins/jsf/pom.xml | 37 +
.../jsf/ApplyRequestValuesInterceptor.java | 75 +
.../apache/struts2/jsf/FacesInterceptor.java | 106 +
.../org/apache/struts2/jsf/FacesRender.java | 76 +
.../org/apache/struts2/jsf/FacesResult.java | 81 +
.../struts2/jsf/FacesSetupInterceptor.java | 587 +
.../org/apache/struts2/jsf/FacesSupport.java | 170 +
.../jsf/InvokeApplicationInterceptor.java | 75 +
.../jsf/ProcessValidationsInterceptor.java | 74 +
.../struts2/jsf/RestoreViewInterceptor.java | 225 +
.../struts2/jsf/StrutsNavigationHandler.java | 83 +
.../struts2/jsf/StrutsVariableResolver.java | 79 +
.../jsf/UpdateModelValuesInterceptor.java | 75 +
.../org/apache/struts2/jsf/package.html | 9 +
.../jsf/src/main/resources/struts-plugin.xml | 38 +
trunk/plugins/pell-multipart/pom.xml | 23 +
.../multipart/PellMultiPartRequest.java | 140 +
trunk/plugins/plexus/pom.xml | 23 +
.../apache/struts2/plexus/PlexusFilter.java | 112 +
.../plexus/PlexusLifecycleListener.java | 112 +
.../struts2/plexus/PlexusObjectFactory.java | 300 +
.../struts2/plexus/PlexusThreadLocal.java | 41 +
.../apache/struts2/plexus/PlexusUtils.java | 50 +
trunk/plugins/pom.xml | 57 +
trunk/plugins/quickstart/pom.xml | 142 +
.../main/java/org/apache/struts2/Main.java | 241 +
.../struts2/quickstart/Configuration.java | 369 +
.../struts2/quickstart/JettyServer.java | 65 +
.../apache/struts2/quickstart/Mapping.java | 51 +
.../quickstart/MultiDirClassLoader.java | 96 +
.../struts2/quickstart/MultiDirResource.java | 211 +
.../MultiWebApplicationContext.java | 158 +
.../apache/struts2/quickstart/QuickStart.java | 200 +
trunk/plugins/sitegraph/pom.xml | 120 +
.../main/java/org/apache/struts2/Main.java | 231 +
.../apache/struts2/sitegraph/SiteGraph.java | 125 +
.../sitegraph/StrutsConfigRetriever.java | 179 +
.../sitegraph/entities/FileBasedView.java | 109 +
.../sitegraph/entities/FreeMarkerView.java | 20 +
.../struts2/sitegraph/entities/JspView.java | 37 +
.../struts2/sitegraph/entities/Target.java | 58 +
.../sitegraph/entities/VelocityView.java | 37 +
.../struts2/sitegraph/entities/View.java | 43 +
.../struts2/sitegraph/model/ActionNode.java | 30 +
.../apache/struts2/sitegraph/model/Graph.java | 88 +
.../struts2/sitegraph/model/IndentWriter.java | 59 +
.../apache/struts2/sitegraph/model/Link.java | 91 +
.../struts2/sitegraph/model/Render.java | 26 +
.../sitegraph/model/SiteGraphNode.java | 64 +
.../struts2/sitegraph/model/SubGraph.java | 129 +
.../struts2/sitegraph/model/ViewNode.java | 30 +
.../sitegraph/renderers/DOTRenderer.java | 254 +
.../struts2/sitegraph/SiteGraphTest.java | 60 +
.../org/apache/struts2/sitegraph/hello.jsp | 1 +
.../org/apache/struts2/sitegraph/out.txt | 32 +
.../org/apache/struts2/sitegraph/struts.xml | 38 +
.../tutorial/sitegraph/guess-error.ftl | 1 +
.../tutorial/sitegraph/guess-input.ftl | 12 +
.../tutorial/sitegraph/guess-success.jsp | 1 +
trunk/plugins/sitemesh/pom.xml | 38 +
.../sitemesh/FreeMarkerPageFilter.java | 170 +
.../struts2/sitemesh/TemplatePageFilter.java | 172 +
.../struts2/sitemesh/VelocityPageFilter.java | 93 +
trunk/plugins/struts1/pom.xml | 29 +
.../s1/ActionFormResetInterceptor.java | 53 +
.../s1/ActionFormValidationInterceptor.java | 225 +
.../struts2/s1/DynaBeanPropertyAccessor.java | 55 +
.../org/apache/struts2/s1/Struts1Action.java | 138 +
.../org/apache/struts2/s1/Struts1Factory.java | 149 +
.../struts2/s1/WrapperActionForward.java | 56 +
.../struts2/s1/WrapperActionMapping.java | 282 +
.../struts2/s1/WrapperExceptionConfig.java | 63 +
.../struts2/s1/WrapperMessageResources.java | 44 +
.../struts2/s1/WrapperModuleConfig.java | 244 +
.../src/main/resources/struts-plugin.xml | 30 +
.../s1/DynaBeanPropertyAccessorTest.java | 134 +
.../apache/struts2/s1/Struts1FactoryTest.java | 234 +
.../apache/struts2/s1/test-struts-factory.xml | 43 +
trunk/plugins/tiles/pom.xml | 29 +
.../struts2/tiles/StrutsTilesListener.java | 61 +
.../struts2/tiles/StrutsTilesUtilImpl.java | 96 +
.../struts2/views/tiles/TilesResult.java | 227 +
.../src/main/resources/struts-plugin.xml | 11 +
trunk/pom.xml | 318 +
trunk/src/main/idea/project.xml | 14 +
trunk/src/main/idea/workspace.xml | 79 +
trunk/src/site/site.xml | 134 +
trunk/src/site/xdoc/index.xml | 50 +
trunk/src/site/xdoc/jxr.xml | 38 +
2057 files changed, 198814 insertions(+)
create mode 100644 trunk/all/pom.xml
create mode 100644 trunk/api/pom.xml
create mode 100644 trunk/api/src/main/java/org/apache/struts2/Action.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/MessageAware.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/Messages.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/ResultNames.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/Validatable.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/spi/ActionContext.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/spi/Interceptor.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/spi/RequestContext.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/spi/Result.java
create mode 100644 trunk/api/src/main/java/org/apache/struts2/spi/ValueStack.java
create mode 100644 trunk/apps/blank/README.txt
create mode 100644 trunk/apps/blank/pom.xml
create mode 100644 trunk/apps/blank/src/main/java/example/ExampleSupport.java
create mode 100644 trunk/apps/blank/src/main/java/example/HelloWorld.java
create mode 100644 trunk/apps/blank/src/main/java/example/Login.java
create mode 100644 trunk/apps/blank/src/main/java/example/build.bat
create mode 100644 trunk/apps/blank/src/main/resources/example.xml
create mode 100644 trunk/apps/blank/src/main/resources/example/Login-validation.xml
create mode 100644 trunk/apps/blank/src/main/resources/example/package.properties
create mode 100644 trunk/apps/blank/src/main/resources/example/package_es.properties
create mode 100644 trunk/apps/blank/src/main/resources/struts.properties
create mode 100644 trunk/apps/blank/src/main/resources/struts.xml
create mode 100644 trunk/apps/blank/src/main/webapp/WEB-INF/applicationContext.xml
create mode 100644 trunk/apps/blank/src/main/webapp/WEB-INF/web.xml
create mode 100644 trunk/apps/blank/src/main/webapp/example/HelloWorld.jsp
create mode 100644 trunk/apps/blank/src/main/webapp/example/Login.jsp
create mode 100644 trunk/apps/blank/src/main/webapp/example/Menu.jsp
create mode 100644 trunk/apps/blank/src/main/webapp/example/Missing.jsp
create mode 100644 trunk/apps/blank/src/main/webapp/example/Register.jsp
create mode 100644 trunk/apps/blank/src/main/webapp/example/Welcome.jsp
create mode 100644 trunk/apps/blank/src/main/webapp/index.html
create mode 100644 trunk/apps/blank/src/test/java/example/ConfigTest.java
create mode 100644 trunk/apps/blank/src/test/java/example/HelloWorldTest.java
create mode 100644 trunk/apps/blank/src/test/java/example/LoginTest.java
create mode 100644 trunk/apps/mailreader/README.txt
create mode 100644 trunk/apps/mailreader/pom.xml
create mode 100644 trunk/apps/mailreader/src/main/java/alternate.properties
create mode 100644 trunk/apps/mailreader/src/main/java/alternate_ja.properties
create mode 100644 trunk/apps/mailreader/src/main/java/applicationContext.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader-default.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader-support.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/ApplicationListener.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Constants.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Login.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Logon-validation.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Logout.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.properties
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Registration-Registration!save-validation.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Registration-validation.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Registration.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Subscription-Subscription!save-validation.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Subscription-validation.xml
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Subscription.java
create mode 100644 trunk/apps/mailreader/src/main/java/mailreader2/Welcome.java
create mode 100644 trunk/apps/mailreader/src/main/java/struts.properties
create mode 100644 trunk/apps/mailreader/src/main/java/struts.xml
create mode 100644 trunk/apps/mailreader/src/main/webapp/ChangePassword.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/Error.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/Footer.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/Login.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/META-INF/context.xml
create mode 100644 trunk/apps/mailreader/src/main/webapp/MainMenu.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/Registration.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/Subscription.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/WEB-INF/database.xml
create mode 100644 trunk/apps/mailreader/src/main/webapp/WEB-INF/web.xml
create mode 100644 trunk/apps/mailreader/src/main/webapp/Welcome.jsp
create mode 100644 trunk/apps/mailreader/src/main/webapp/css/mailreader.css
create mode 100644 trunk/apps/mailreader/src/main/webapp/index.html
create mode 100644 trunk/apps/mailreader/src/main/webapp/struts-power.gif
create mode 100644 trunk/apps/mailreader/src/main/webapp/tour.html
create mode 100644 trunk/apps/pom.xml
create mode 100644 trunk/apps/portlet/README.txt
create mode 100644 trunk/apps/portlet/pom.xml
create mode 100644 trunk/apps/portlet/src/main/etc/exo/web.xml
create mode 100644 trunk/apps/portlet/src/main/etc/gridsphere/README-gridsphere.txt
create mode 100644 trunk/apps/portlet/src/main/etc/gridsphere/gridsphere-portlet.xml
create mode 100644 trunk/apps/portlet/src/main/etc/gridsphere/group.xml
create mode 100644 trunk/apps/portlet/src/main/etc/gridsphere/layout.xml
create mode 100644 trunk/apps/portlet/src/main/etc/gridsphere/struts-portlet
create mode 100644 trunk/apps/portlet/src/main/etc/gridsphere/web.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-app.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-portlet.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-web.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.0/portlet-instances.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.0/struts-portlet-pages.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-app.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-portlet.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-web.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jbossportal2.2/struts-portlet-object.xml
create mode 100644 trunk/apps/portlet/src/main/etc/jetspeed2/README-jetspeed2.txt
create mode 100644 trunk/apps/portlet/src/main/etc/jetspeed2/struts-portlet.psml
create mode 100644 trunk/apps/portlet/src/main/etc/liferay3.6.1/web.xml
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/ExampleAction.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExample.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExampleWithValidation.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormResultAction.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormTestAction.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/SavePrefsAction.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/SpringAction.java
create mode 100644 trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/ThingManager.java
create mode 100644 trunk/apps/portlet/src/main/resources/commons-logging.properties
create mode 100644 trunk/apps/portlet/src/main/resources/log4j.xml
create mode 100644 trunk/apps/portlet/src/main/resources/org/apache/struts2/portlet/example/FormExample-processValidationExample-validation.xml
create mode 100644 trunk/apps/portlet/src/main/resources/struts.properties
create mode 100644 trunk/apps/portlet/src/main/resources/template/xhtml/components/checkbox.vm
create mode 100644 trunk/apps/portlet/src/main/resources/template/xhtml/components/datefield.vm
create mode 100644 trunk/apps/portlet/src/main/resources/template/xhtml/components/mytextfield.vm
create mode 100644 trunk/apps/portlet/src/main/resources/validators.xml
create mode 100644 trunk/apps/portlet/src/main/resources/xwork.xml
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/applicationContext.xml
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/dwr.xml
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/defaultEdit.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExample.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExampleInput.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/index.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/namespaceTest.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsForm.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsSaved.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/edit/test.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/help/defaultHelp.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/help/index.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/portlet.xml
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/readme.txt
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajax.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxData.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxExample.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExample.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInput.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInputValidation.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExample.ftl
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExampleInput.ftl
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/helloWorld.vm
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/index.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/notImplemented.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/springExample.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExample.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExampleInput.jsp
create mode 100644 trunk/apps/portlet/src/main/webapp/WEB-INF/web.xml
create mode 100644 trunk/apps/portlet/src/main/webapp/styles/styles.css
create mode 100644 trunk/apps/showcase/README.txt
create mode 100644 trunk/apps/showcase/pom.xml
create mode 100644 trunk/apps/showcase/quickstart.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DynamicTreeSelectAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/Guess.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfOptiontransferselectAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ShowDynamicTreeAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction_de.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction_de.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain1.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain2.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain3.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/AjaxTestAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example4ShowPanelAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example5Action.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Category.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/GetCategory.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Toggle.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/MemoryStorage.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/Storage.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatAuthenticationInterceptor.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatInterceptor.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLoginAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLogoutAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatMessage.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatService.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatServiceImpl.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatSessionListener.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Constants.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/CrudRoomAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/DateConverter.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/EnterRoomAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ExitRoomAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/MessagesAvailableInRoomAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Room.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/RoomsAvailableAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/SendMessageToRoomAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/User.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableInRoomAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Address.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/EnumTypeConverter.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnum.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Person.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/AbstractDao.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/Dao.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/EmployeeDao.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/SkillDao.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/CreateException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DeleteException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DuplicateKeyException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/StorageException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/UpdateException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/filedownload/FileDownloadAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/FileUploadAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManager.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManagerUtil.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GetUpdatedHangmanAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GuessCharacterAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Hangman.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanConstants.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanException.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanService.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/PropertiesVocabSource.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/StartHangmanAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Vocab.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/VocabSource.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/EditGangsterAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/GangsterForm.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/SaveGangsterAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/jsf/JsfEmployeeAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Employee.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/IdEntity.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Skill.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/Gangster.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/ListPeople.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/PersonManager.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/sitemesh/NoneDecoratorMapper.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actionPrefix/SubmitAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actiontag/ActionTagDemo.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/AppendIteratorTagDemo.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/MergeIteratorTagDemo.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/SubsetIteratorTagDemo.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/token/TokenAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName2.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloWorld.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AbstractValidationActionSupport.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/SubmitApplication.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User-userContext-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction.java
create mode 100644 trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/wait/LongProcessAction.java
create mode 100644 trunk/apps/showcase/src/main/resources/globalMessages.properties
create mode 100644 trunk/apps/showcase/src/main/resources/globalMessages_de.properties
create mode 100644 trunk/apps/showcase/src/main/resources/log4j.properties
create mode 100644 trunk/apps/showcase/src/main/resources/myTemplateDir/myTheme/myAnotherTemplate.ftl
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/DateAction.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/UITagExample-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction_de.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction_de.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/ajax/Example5Action-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatLoginAction-chatLogin-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatMessage-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/CrudRoomAction-createRoom-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/Room-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/SendMessageToRoomAction-sendMessageToRoom-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/CreatePerson-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/EditPerson-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/Person-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/QuizAction-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/SubmitApplication-submitApplication-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/User-userContext-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-actionchaining.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-ajax.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-chat.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-continuations.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-conversion.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-filedownload.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-fileupload.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-freemarker.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-hangman.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-integration.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-jsf.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-model-driven.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-person.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-tags-non-ui.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-tags-ui.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-tags.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-token.xml
create mode 100755 trunk/apps/showcase/src/main/resources/struts-validation.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts-wait.xml
create mode 100644 trunk/apps/showcase/src/main/resources/struts.properties
create mode 100644 trunk/apps/showcase/src/main/resources/struts.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/applicationContext.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/decorators.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/dwr.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-decorator.tld
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-page.tld
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/validation.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml
create mode 100644 trunk/apps/showcase/src/main/webapp/actionchaining/actionChainingResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/AjaxResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/AjaxResult2.js
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/AjaxResult3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/commonInclude.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/footer.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example1.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example2.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example4.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example5.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example6.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example7.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/example8.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotediv/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remoteforms/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test1.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test2.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/remotelink/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example1.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example2.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example4.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5Ok.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel1.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2Submit.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3Submit.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/testjs.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tree/getCategory.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tree/partialChunkHeader.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tree/toggle.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/tree/tree.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/ajax/widgets/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/chatLogin.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/createRoom.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/messagesAvailableInRoom.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/roomSelection.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/roomsAvailable.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/sendMessageToRoomResult.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/showRoom.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/usersAvailable.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/chat/usersAvailableInRoom.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/continuations/guess.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/Address.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/AddressAction.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/EnumTypeConverter.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/OperationsEnum.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumAction.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumActionConversion.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/Person.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/PersonAction.java.txt
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/enterAddressInfo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/enterOperations.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/enterPersonInfo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/showAddressInfo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/showOperations.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/conversion/showPersonInfo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/ftlCustomTemplate.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/jspCustomTemplate.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/date.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/empmanager/editEmployee.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/empmanager/editSkill.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/empmanager/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/empmanager/listEmployees.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/empmanager/listSkills.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/filedownload/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/fileupload/upload-success.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/fileupload/upload.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/freemarker/customFreemarkerManagerUsage.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/freemarker/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/blank.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/hangmanAjax.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/hangmanMenu.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/hangmanNonAjax.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_0.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_1.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_2.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_3.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_4.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_5.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_A.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_B.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_C.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_D.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_E.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_F.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_G.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_H.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_I.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_J.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_K.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_L.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_M.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_N.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_O.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_P.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Q.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_R.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_S.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_T.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_U.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_V.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_W.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_X.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Y.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Z.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_underscroll.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/choose.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/guess.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/guesses-left.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/hangman.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/letter-spacer.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/play-again.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_-1.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_0.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_1.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_2.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_3.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_4.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_5.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/start.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/you-lose.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/images/you-win.png
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/test.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/updateCharacterAvailable.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/updateGuessLeft.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/updateScaffold.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/hangman/updateVocabCharacters.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/help.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/images/struts-power.gif
create mode 100644 trunk/apps/showcase/src/main/webapp/images/struts.gif
create mode 100644 trunk/apps/showcase/src/main/webapp/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/integration/modelDriven.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/integration/modelDrivenResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/jsf/employee/edit.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/jsf/employee/list.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/jsf/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/modelDriven/modelDriven.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/modelDriven/modelDrivenResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/person/editPeople.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/person/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/person/listPeople.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/person/newPerson.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/showcase.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/forms.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/layout-navtop-1col.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/layout-navtop-localleft.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/layout.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/main.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/nav-horizontal.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/tools.css
create mode 100644 trunk/apps/showcase/src/main/webapp/styles/typo.css
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/actionPrefix.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/actionPrefixExample.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/methodPrefix.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/normalSubmit.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionPrefix/redirectActionPrefix.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionTag/includedPage.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionTag/includedPage2.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionTag/includedPage3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/actionTag/showActionTagDemo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/date.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/debug.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/ifTag/testIf.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/ifTag/testIf.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/appendIteratorTagDemoResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/iteratorGeneratorTagDemoResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/mergeIteratorTagDemoResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/showAppendIteratorTagDemo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/showIteratorGeneratorTagDemo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/showMergeIteratorTagDemo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/subsetIteratorTagDemo.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/non-ui/iteratorTag/subsetIteratorTagDemoResult.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/componentTagExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/dynamicTreeSelect.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/example.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/example.vm
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/exampleSubmited.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/exampleSubmited.vm
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/images/backgroundImage.jpg
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/images/leopard.jpg
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/lotsOfOptiontransferselect.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/lotsOfOptiontransferselectSubmit.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/staticTreeSelect.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/treeExampleDynamic.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/tags/ui/treeExampleStatic.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/template/xhtml/mytemplate.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/token/doublePost.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/token/example1.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/token/example2.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/token/example3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/token/example4.ftl
create mode 100644 trunk/apps/showcase/src/main/webapp/token/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/token/transferDone.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/clientSideValidationExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/fieldValidatorsExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/footer.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/nonFieldValidatorsExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/quiz-ajax.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/quiz-basic.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/quiz-client-css.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/quiz-client.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/quiz-success.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/storeErrorsAcrossRequestCancel.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/storeErrorsAcrossRequestExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/storeErrorsAcrossRequestOk.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/successClientSideValidationExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/successFieldValidatorsExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/successNonFieldValidatorsExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/successVisitorValidatorsExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/validationExamplesStyles.css
create mode 100644 trunk/apps/showcase/src/main/webapp/validation/visitorValidatorsExample.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/viewSource.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/wait/complete.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/wait/example1.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/wait/example2.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/wait/example3.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/wait/index.jsp
create mode 100644 trunk/apps/showcase/src/main/webapp/wait/wait.jsp
create mode 100644 trunk/apps/showcase/src/test/java/org/apache/struts2/showcase/tutorial/HelloTest.java
create mode 100644 trunk/assembly/pom.xml
create mode 100644 trunk/assembly/src/main/assembly/all.xml
create mode 100644 trunk/assembly/src/main/assembly/apps.xml
create mode 100644 trunk/assembly/src/main/assembly/lib.xml
create mode 100644 trunk/assembly/src/main/assembly/src.xml
create mode 100644 trunk/assembly/src/main/resources/LICENSE.txt
create mode 100644 trunk/assembly/src/main/resources/NOTICE.txt
create mode 100644 trunk/assembly/src/main/resources/build.xml
create mode 100755 trunk/backport/ASM-LICENSE.txt
create mode 100644 trunk/backport/LICENSE.txt
create mode 100755 trunk/backport/RETROTRANSLATOR-LICENSE.txt
create mode 100755 trunk/backport/S2-FOR-J4-README.txt
create mode 100755 trunk/backport/STRUTS-LICENSE.txt
create mode 100755 trunk/backport/XWORK-LICENSE.txt
create mode 100755 trunk/backport/backport-util-concurrent.jar
create mode 100644 trunk/backport/readme.html
create mode 100755 trunk/backport/retrotranslator-runtime-1.0.7.jar
create mode 100644 trunk/backport/retrotranslator-runtime-1.0.8.jar
create mode 100644 trunk/backport/retrotranslator-transformer-1.0.8.jar
create mode 100644 trunk/backport/translate.bat
create mode 100644 trunk/core/pom.xml
create mode 100644 trunk/core/src/main/etc/taglib-settings.xml
create mode 100644 trunk/core/src/main/java/org/apache/struts2/RequestUtils.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/ServletActionContext.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/StrutsConstants.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/StrutsException.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/StrutsStatics.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/StrutsTestCase.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ActionComponent.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ActionError.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ActionMessage.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Anchor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/AppendIterator.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Bean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Checkbox.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/CheckboxList.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ClosingUIBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ComboBox.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Component.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Date.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/DatePicker.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Debug.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Div.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/DoubleListUIBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/DoubleSelect.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Else.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ElseIf.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/FieldError.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/File.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Form.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/FormButton.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/GenericUIBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Head.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Hidden.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/I18n.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/If.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Include.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/IteratorComponent.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Label.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/ListUIBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/MergeIterator.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/OptGroup.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/OptionTransferSelect.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Panel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Param.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Password.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Property.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Push.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Radio.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/RemoteCallUIBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Reset.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Select.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Set.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Submit.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/TabbedPanel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Text.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/TextArea.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/TextField.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/TimePicker.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Token.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/Tree.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/TreeNode.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/UIBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/URL.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/UpDownSelect.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/AbstractFilterModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/RenderFilterModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/SortFilterModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/SortableTableModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/WebTable.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/WebTableColumn.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/AbstractCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/BooleanCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/CellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/DateCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/DefaultCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/FixedTextCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/LinkCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/NumericCellRenderer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/table/renderer/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/BaseTemplateEngine.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/FreemarkerTemplateEngine.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/JspTemplateEngine.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/Template.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/TemplateEngine.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/TemplateEngineManager.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/TemplateRenderingContext.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/components/template/VelocityTemplateEngine.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/DefaultSettings.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/DelegatingSettings.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/PropertiesSettings.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/ServletContextSingleton.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/Settings.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/StrutsXmlConfigurationProvider.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/config/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/ActionContextCleanUp.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/ApplicationMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/DefaultActionSupport.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/DispatcherListener.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcher.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/FilterDispatcherCompatWeblogic61.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/HttpHeaderResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/PlainTextResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/RequestMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletActionRedirectResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletDispatcherResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/ServletRedirectResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/SessionMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/StreamResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/StrutsRequestWrapper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/StrutsResultSupport.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/VelocityResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapperFactory.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/ActionMapping.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/mapper/RestfulActionMapper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/multipart/JakartaMultiPartRequest.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequest.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/multipart/MultiPartRequestWrapper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/multipart/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/dispatcher/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/ActionContextImpl.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/InterceptorAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/MessagesImpl.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/RequestContextImpl.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/ResultAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/StrutsActionProxy.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/StrutsActionProxyFactory.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/StrutsObjectFactory.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/impl/ValueStackAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ApplicationAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/BackgroundProcess.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/CheckboxInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/CreateSessionInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/FileUploadInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/MessageStoreInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/NoParameters.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ParameterAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/PrincipalAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/PrincipalProxy.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ProfilingActivationInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/RequestAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ScopeInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ServletConfigInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ServletRequestAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/ServletResponseAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/SessionAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/StrutsConversionErrorInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/TokenInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/debugging/DebuggingInterceptor.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/interceptor/debugging/PrettyPrintWriter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/PortletActionConstants.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/PortletApplicationMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/PortletRequestMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/PortletSessionMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/context/PortletActionContext.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/context/PreparatorServlet.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/context/ServletContextHolderListener.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/dispatcher/DirectRenderFromEventAction.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/dispatcher/Jsr168Dispatcher.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/result/PortletResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/result/PortletVelocityResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/portlet/util/PortletUrlHelper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/spring/StrutsSpringObjectFactory.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/spring/lifecycle/SpringExternalReferenceResolverSetupListener.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/AppendIteratorFilter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/AttributeMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ClassLoaderUtils.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ContainUtil.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/Counter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/DateFormatter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/FastByteArrayOutputStream.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/InvocationSessionStore.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/IteratorFilterSupport.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/IteratorGenerator.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ListEntry.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/MakeIterator.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/MergeIteratorFilter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ObjectFactoryDestroyable.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ObjectFactoryInitializable.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ObjectFactoryLifecycle.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/PrefixTrie.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ResolverSetupServletContextListener.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/ServletContextAware.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/SortIteratorFilter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/Sorter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/StrutsTypeConverter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/StrutsUtil.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/SubsetIteratorFilter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/TabbedPane.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/Timer.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/TokenHelper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/URLBean.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/util/VelocityStrutsUtil.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/validators/DWRValidator.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/JspSupportServlet.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerManager.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/FreemarkerResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/PortletFreemarkerResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/ScopesHashModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/StrutsBeanWrapper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/StrutsClassTemplateLoader.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionErrorModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionMessageModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ActionModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/AnchorModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/BeanModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/CallbackWriter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/CheckboxListModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/CheckboxModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ComboBoxModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ComponentModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/DateModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/DatePickerModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/DivModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/DoubleSelectModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ElseIfModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ElseModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/FieldErrorModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/FileModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/FormModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/HeadModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/HiddenModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/I18nModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/IfModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/IncludeModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/IteratorModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/LabelModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/OptGroupModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/OptionTransferSelectModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/PanelModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ParamModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/PasswordModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/PropertyModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/PushModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/RadioModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/ResetModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/SelectModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/SetModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/StrutsModels.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/SubmitModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TabbedPanelModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TagModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TextAreaModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TextFieldModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TextModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TimePickerModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TokenModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TreeModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/TreeNodeModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/URLModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/UpDownSelectModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/freemarker/tags/WebTableModel.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ActionTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/BeanTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ComponentTagSupport.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/DateTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ElseIfTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ElseTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/I18nTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/IfTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/IncludeTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/IteratorStatus.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/IteratorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ParamTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/PropertyTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/PushTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/SetTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/StrutsBodyTagSupport.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/TagUtils.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/TextTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/URLTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/iterator/AppendIteratorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/iterator/IteratorGeneratorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/iterator/MergeIteratorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/iterator/SortIteratorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/iterator/SubsetIteratorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractClosingTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractDoubleListTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractListTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractRequiredListTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AbstractUITag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionErrorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/ActionMessageTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AnchorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxListTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/CheckboxTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/ComboBoxTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/ComponentTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/DatePickerTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/DebugTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/DivTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/DoubleSelectTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/FieldErrorTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/FileTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/FormTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/HeadTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/HiddenTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/LabelTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/OgnlTool.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/OptGroupTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/PanelTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/PasswordTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/RadioTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/ResetTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/SelectTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/SubmitTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TabbedPanelTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TextFieldTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TextareaTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TimePickerTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TokenTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TreeNodeTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/TreeTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/UpDownSelectTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/table/WebTableTag.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/util/ContextUtil.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/util/ResourceUtil.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/util/TextUtil.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/util/UrlHelper.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/util/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/StrutsResourceLoader.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/StrutsVelocityContext.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/StrutsVelocityServlet.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/VelocityManager.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/AbstractDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ActionDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ActionErrorDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ActionMessageDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/AnchorDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/BeanDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/CheckBoxDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/CheckBoxListDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ComboBoxDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ComponentDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/DateDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/DatePickerDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/DivDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/DoubleSelectDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/FieldErrorDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/FileDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/FormDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/HeadDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/HiddenDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/I18nDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/IncludeDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/LabelDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/OptGroupDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/OptionTransferSelectDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/PanelDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ParamDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/PasswordDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/PropertyDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/PushDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/RadioDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/ResetDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/SelectDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/SetDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/SubmitDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TabbedPanelDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TextAreaDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TextDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TextFieldDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TokenDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TreeDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/TreeNodeDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/URLDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/UpDownSelectDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/components/WebTableDirective.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/velocity/package.html
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterElement.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/AbstractAdapterNode.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterFactory.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/AdapterNode.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ArrayAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/BeanAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/CollectionAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/MapAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyAttrAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyElementAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNamedNodeMap.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyNodeAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ProxyTextNodeAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/ServletURIResolver.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleAdapterDocument.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleNodeList.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/SimpleTextNode.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/StringAdapter.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/XSLTResult.java
create mode 100644 trunk/core/src/main/java/org/apache/struts2/views/xslt/package.html
create mode 100644 trunk/core/src/main/resources/META-INF/struts-tags.tld
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/default.properties
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/dispatcher/error.ftl
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/interceptor/debugging/console.ftl
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/interceptor/debugging/webconsole.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/interceptor/debugging/webconsole.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/interceptor/debugging/webconsole.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/interceptor/package.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/interceptor/wait.ftl
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/package.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/sitegraph/sitegraph-usage.txt
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/CommonFunctions.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/LICENSE
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/README
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/build.txt
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/dojo.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/dojo.js.uncompressed.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/alg/Alg.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/alg/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/animation/Animation.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/animation/Timer.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/animation/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/bootstrap1.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/bootstrap2.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/browser_debug.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/ArrayList.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/BinaryTree.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/ByteArray.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/Collections.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/Dictionary.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/Graph.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/List.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/Queue.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/Set.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/SkipList.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/SortedList.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/Stack.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/collections/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/Blowfish.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/LICENSE
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/MD5.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/Rijndael.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/SHA.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/SHA1.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/SHA256.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/crypto/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/data.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/data/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/date.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/DragAndDrop.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/HtmlDragAndDrop.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/HtmlDragManager.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/HtmlDragMove.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/Sortable.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/TreeDragAndDrop.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dnd/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/dom.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/event.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/event/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/event/browser.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/event/topic.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/flash.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/flash/flash6/DojoExternalInterface.as
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/flash/flash8/DojoExternalInterface.as
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/fx/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/fx/html.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/fx/svg.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/graphics/Colorspace.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/graphics/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/graphics/color.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/graphics/htmlEffects.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_adobesvg.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_browser.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_jsc.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_rhino.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_spidermonkey.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_svg.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/hostenv_wsh.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/html.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/iCalendar.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/BrowserIO.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/IframeIO.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/RepubsubIO.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/RhinoIO.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/cookie.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/io/cookies.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/json.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/lang.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/lang/Lang.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/lang/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/logging/Logger.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/logging/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/math.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/math/Math.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/math/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/math/curves.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/math/matrix.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/math/points.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/profile.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/reflect/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/reflect/reflection.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/regexp.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/rpc/Deferred.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/rpc/JotService.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/rpc/JsonService.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/rpc/RpcService.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/rpc/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/selection.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/storage.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/storage/Storage.as
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/storage/Storage.swf
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/storage/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/storage/browser.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/storage/storage.sh
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/string.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/string/Builder.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/string/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/style.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/svg.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/text/Builder.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/text/String.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/text/Text.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/text/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/text/textDirectory.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/undo/Manager.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/uri/Uri.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/uri/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/validate.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/DomWidget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/HtmlWidget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/SvgWidget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/Widget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/WidgetManager.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/Button.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/ComboBox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/ContextMenu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/DropdownButtons.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/HTMLButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/HTMLComboBox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/HTMLContextMenu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/HTMLMenu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/HTMLMenuItem.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/HTMLResizableTextarea.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/InlineEditBox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/Menu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/MenuItem.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/Parse.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/SVGButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/SlideShow.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/Tabs.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/webui/widgets/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Accordion.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Button.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Button2.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Chart.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Checkbox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/CiviCrmDatePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ColorPalette.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ComboBox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Container.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ContentPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ContextMenu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/DatePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/DebugConsole.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Dialog.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/DomWidget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/DropdownButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Editor.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/EditorTree.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/EditorTreeContextMenu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/EditorTreeController.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/EditorTreeNode.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/EditorTreeSelector.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/FisheyeList.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/FloatingPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/HslColorPicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/HtmlWidget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/InlineEditBox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/LayoutPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/LinkPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Manager.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Menu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Menu2.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/MenuItem.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Parse.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/PopUpButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ResizableTextarea.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ResizeHandle.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/RichText.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SimpleDropdownButtons.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SlideShow.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SplitPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/SvgWidget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TabPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Tabs.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TaskBar.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TemplatedContainer.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/TimePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Toggler.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Toolbar.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Tooltip.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Tree.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Widget.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/Wizard.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/Button.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/Button2.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/Checkbox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/ComboBox.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/Container.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/ContentPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/ContextMenu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/DatePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/DebugConsole.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/DropdownButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/LayoutPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/LinkPane.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/Menu.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/MenuItem.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/TaskBar.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/TimePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/Tooltip.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/html/stabile.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/svg/Chart.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/svg/HslColorPicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/AccordionPanel.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/AccordionPanel.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HslColorPicker.svg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlButton2Template.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlButton2Template.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlButtonTemplate.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlButtonTemplate.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlCiviCrmDatePicker.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlComboBox.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlComboBox.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlComboButton2Template.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlContextMenuTemplate.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlDatePicker.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlDatePicker.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlDialog.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlDropDownButtonTemplate.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlFisheyeList.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlFloatingPane.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlInlineEditBox.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlInlineEditBox.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlLayoutPane.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlMenu2.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlMenuItemTemplate.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlResizableTextarea.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlResizableTextarea.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlResizeHandle.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlSimpleDropdownButtons.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlSlideShow.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlSlideShow.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlSplitPane.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTabPane.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTabs.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTaskBar.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTaskBarItemTemplate.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTimePicker.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTimePicker.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlToolbar.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTooltipTemplate.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/HtmlTooltipTemplate.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/Menu.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/PopUpButton.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/Tree.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/Wizard.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/Wizard.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/-.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/backcolor.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/bold.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/cancel.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/copy.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/createlink.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/cut.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/delete.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/forecolor.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/hilitecolor.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/indent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/inserthorizontalrule.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/insertimage.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/insertorderedlist.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/inserttable.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/insertunorderedlist.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/italic.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/justifycenter.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/justifyfull.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/justifyleft.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/justifyright.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/left_to_right.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/list_bullet_indent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/list_bullet_outdent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/list_num_indent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/list_num_outdent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/outdent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/paste.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/redo.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/removeformat.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/right_to_left.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/save.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/space.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/strikethrough.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/subscript.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/superscript.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/underline.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/undo.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/buttons/wikiword.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/check_off.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/check_on.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/decrementMonth.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/decrementWeek.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/grabCorner.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/EditorTree.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/blank.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/closed.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/document.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/minus.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/open.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/plus.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_blank.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_child.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_expand_minus.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_expand_plus.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_c.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_l.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_p.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_t.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_v.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_x.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_y.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_grid_z.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/EditorTree/treenode_loading.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/blank.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/combo_box_arrow.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/dropdownButtonsArrow-disabled.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/dropdownButtonsArrow.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/floatingPaneClose.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/floatingPaneMaximize.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/floatingPaneMinimize.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/floatingPaneRestore.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/hue.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/no.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/no.svg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-blue_benji-c.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-blue_benji-l.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-blue_benji-r.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-blue_benji_p_01.svg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-gray_benji-c.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-gray_benji-l.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-gray_benji-r.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-gray_benji.svg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-purple_benji-c.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-purple_benji-l.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-purple_benji-r.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-purple_benji_01.svg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-seagreen_ben_01.svg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-seagreen_benji-c.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-seagreen_benji-l.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/pill-button-seagreen_benji-r.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowB.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowBL.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowBR.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowL.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowR.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowTR..png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowUL.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/shadowUR.png
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/submenu_off.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/submenu_on.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/tab_left.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/tab_left_r.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/tab_left_r_curr.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/tab_right.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/tab_right_r.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/tab_right_r_curr.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/titlebar-bg.jpg
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/toolbar-bg.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/transparent.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_blank.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_expand_minus.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_expand_plus.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_c.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_l.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_p.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_t.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_v.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_x.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_y.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_grid_z.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/treenode_node.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/verticalbar.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/images/whiteDownArrow.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/incrementMonth.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/templates/incrementWeek.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/xml/Parse.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/xml/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/xml/domUtil.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/xml/htmlUtil.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/xml/svgUtil.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/Util.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/tooltip.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/Bind.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/Bind.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/BindAnchor.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/BindAnchor.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/BindButton.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/BindButton.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/BindDiv.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/BindDiv.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/DateTimeUtil.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/DropDownDatePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/DropDownTimePicker.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/DropdownContainer.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/DynArchCalendar.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/DynArchCalendar.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/ToggleBindDiv.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/__package__.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/dateIcon.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/dropdowncontainer.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/dropdowncontainer.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widgets/timeIcon.gif
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/niftycorners/layout.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/niftycorners/nifty.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/niftycorners/niftyCorners.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/niftycorners/niftyPrint.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/niftycorners/niftylayout.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/optiontransferselect.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/tabs.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/tree.css
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/static/validationClient.js
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/struts-messages.properties
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/struts-messages_da.properties
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/struts-messages_de.properties
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/util/package.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/views/freemarker/package.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/views/jsp/iterator/package.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/views/jsp/ui/package.html
create mode 100644 trunk/core/src/main/resources/org/apache/struts2/views/jsp/ui/table/package.html
create mode 100644 trunk/core/src/main/resources/overview.html
create mode 100644 trunk/core/src/main/resources/struts-2.0.dtd
create mode 100644 trunk/core/src/main/resources/struts-default.xml
create mode 100644 trunk/core/src/main/resources/struts-plugin-default.xml
create mode 100644 trunk/core/src/main/resources/struts.vm
create mode 100644 trunk/core/src/main/resources/template/ajax/a.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/controlheader.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/div.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/dojoRequire.js
create mode 100644 trunk/core/src/main/resources/template/ajax/form-close.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/form.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/head.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/submit-ajax.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/submit.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/tab-close.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/tab.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/textarea.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/theme.properties
create mode 100644 trunk/core/src/main/resources/template/ajax/tree-close.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/tree.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/treenode-close.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/treenode-include.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/treenode.ftl
create mode 100644 trunk/core/src/main/resources/template/ajax/validation.js
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/a-close.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/a.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/div-close.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/div.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/form-close.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/form.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/submit.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/tab-close.vm
create mode 100644 trunk/core/src/main/resources/template/archive/ajax/tab.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/checkbox.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/checkboxlist.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/combobox.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/debug.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/doubleselect.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/empty.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/file.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/form-close.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/form.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/hidden.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/label.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/password.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/radiomap.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/scripting-events.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/select.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/submit.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/table.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/text.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/textarea.vm
create mode 100644 trunk/core/src/main/resources/template/archive/simple/token.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/checkbox.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/checkboxlist.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/combobox.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/controlfooter.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/controlheader.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/debug.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/doubleselect.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/empty.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/file.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/form-close.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/form.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/hidden.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/label.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/password.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/radiomap.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/select.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/submit.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/table.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/text.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/textarea.vm
create mode 100644 trunk/core/src/main/resources/template/archive/xhtml/token.vm
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/checkbox.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/checkboxlist.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/combobox.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/control-close.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/control.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/controlfooter.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/controlheader-core.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/controlheader.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/datepicker.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/debug.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/doubleselect.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/file.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/form-close.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/form-validate.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/form.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/head.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/label.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/optiontransferselect.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/password.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/radiomap.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/reset.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/select.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/styles.css
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/submit.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/text.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/textarea.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/theme.properties
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/updownselect.ftl
create mode 100644 trunk/core/src/main/resources/template/css_xhtml/validation.js
create mode 100644 trunk/core/src/main/resources/template/simple/a-close.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/a.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/actionerror.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/actionmessage.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/checkbox.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/checkboxlist.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/combobox.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/common-attributes.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/controlfooter.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/controlheader.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/datepicker.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/debug.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/div-close.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/div.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/dojoRequire.js
create mode 100644 trunk/core/src/main/resources/template/simple/doubleselect.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/empty.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/fielderror.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/file.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/form-close.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/form.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/head.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/hidden.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/label.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/optgroup.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/optiontransferselect.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/password.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/radiomap.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/reset.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/scripting-events.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/select.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/submit.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/tab-close.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/tab.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/tabbedpanel-close.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/tabbedpanel.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/table.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/text.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/textarea.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/timepicker.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/token.ftl
create mode 100644 trunk/core/src/main/resources/template/simple/updownselect.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/checkbox.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/checkboxlist.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/combobox.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/control-close.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/control.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/controlfooter.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/controlheader-core.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/controlheader.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/datepicker.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/debug.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/doubleselect.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/file.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/form-close-validate.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/form-close.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/form-validate.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/form.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/head.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/label.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/optiontransferselect.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/password.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/radiomap.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/reset.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/select.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/styles.css
create mode 100644 trunk/core/src/main/resources/template/xhtml/submit.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/text.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/textarea.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/theme.properties
create mode 100644 trunk/core/src/main/resources/template/xhtml/timepicker.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/tooltip.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/updownselect.ftl
create mode 100644 trunk/core/src/main/resources/template/xhtml/validation.js
create mode 100644 trunk/core/src/main/xdt/Readme-tagdoclet.txt
create mode 100644 trunk/core/src/main/xdt/tagdoc-toc.xdt
create mode 100644 trunk/core/src/main/xdt/tagdoc.xdt
create mode 100644 trunk/core/src/main/xdt/tags_tld.xdt
create mode 100644 trunk/core/src/test/java/org/apache/struts2/ExecutionCountTestAction.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/RequestUtilsTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/ServletActionContextTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/TestAction.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/TestActionTagResult.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/TestConfigurationProvider.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/TestResult.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/ComponentTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/FormButtonTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/FormTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/PropertyTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/UIBeanTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/UIComponentTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/components/template/BaseTemplateEngineTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/config/SettingsTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/config/TestSettings.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/FilterDispatcherTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/HttpHeaderResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/NullActionMapper.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/PlainTextResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletActionRedirectResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletDispatchedTestAssertInterceptor.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletDispatcherResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/ServletRedirectResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/SessionMapTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/StreamResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/StrutsResultSupportTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/VelocityResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/DefaultActionMapperTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/dispatcher/mapper/RestfulActionMapperTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/impl/MessagesTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/impl/RequestContextTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/CreateSessionInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitDelayAction.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/ExecuteAndWaitInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/ServletConfigInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/StrutsConversionErrorInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/interceptor/TokenSessionStoreInterceptorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/PortletApplicationMapTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/PortletRequestMapTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/PortletSessionMapTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/context/PortletActionContextTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/context/PreparatorServletTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/context/ServletContextHolderListenerTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/dispatcher/Jsr168DispatcherTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/result/PortletResultTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/util/PortletUrlHelperTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/portlet/util/StrutsUtilTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/spring/StrutsSpringObjectFactoryTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/util/CounterTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/util/InvocationSessionStoreTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/util/PrefixTrieTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/util/StrutsTypeConverterTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/util/TokenHelperTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/TemplateEngineManagerTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreemarkerManagerTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/freemarker/FreemarkerTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/freemarker/TestAction.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/freemarker/TestBean.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/AbstractTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/AbstractUITagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/AnchorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/AppendIteratorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/BeanTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ElseIfTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ElseTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/IfTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/IncludeTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/IteratorGeneratorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/IteratorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/MergeIteratorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/PortletUrlTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/PropertyTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/PushTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/SetTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/SortIteratorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockBodyContent.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockHttpServletRequest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockHttpServletResponse.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockHttpSession.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockJspWriter.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockPageContext.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/StrutsMockServletContext.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/SubsetIteratorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionErrorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/ActionMessageTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/AnchorTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/Category.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxListTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/CheckboxTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/ComboBoxTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/ComponentTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/DatePickerTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/DateTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/DivTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/DoubleSelectTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FieldErrorTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FileTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/FormTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/HeadTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/JspTemplateTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/LabelTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/MockTag.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/OptGroupTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/OptionTransferSelectTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/PasswordTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/RadioTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/ResetTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/SelectTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/StrutsBodyContent.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitAjaxTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/TestAction1.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/TextareaTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/TextfieldTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/TokenTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/TooltipTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/TreeTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/UpDownSelectTagTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/User.java
create mode 100755 trunk/core/src/test/java/org/apache/struts2/views/util/ContextUtilTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/util/ResourceUtilTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/util/TextUtilTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/util/UrlHelperTest.java
create mode 100644 trunk/core/src/test/java/org/apache/struts2/views/xslt/XSLTResultTest.java
create mode 100644 trunk/core/src/test/resources/XSLTResultTest.xsl
create mode 100644 trunk/core/src/test/resources/XSLTResultTest2.xsl
create mode 100644 trunk/core/src/test/resources/XSLTResultTest3.xsl
create mode 100644 trunk/core/src/test/resources/log4j.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/TestAction-validation.xml
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/TestAction.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/components/template/dummy.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/components/template/theme1/themeThroughClassPath.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/components/template/theme1/themeThroughFileSystem.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/components/tempo.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/dispatcher/someJspFile.jsp
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/interceptor/FileUploadInterceptor.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/othertest.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/spring/StrutsSpringObjectFactoryTest-applicationContext.xml
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Checkbox-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Checkbox-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Checkbox-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Checkbox-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Checkbox-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/CheckboxList-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/CheckboxList-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/CheckboxList-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/CheckboxList-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/ComboBox-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/ComboBox-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/ComboBox-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Component-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Component-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Component-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Component-param.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/DatePickerTagTest-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/DatePickerTagTest-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/DoubleSelect-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/File-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-10.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-11.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-6.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-7.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-8.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Formtag-9.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/HeadTagTest-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Hidden-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Label-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Label-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Label-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/OptGroup-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/OptGroup-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/OptGroup-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Password-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Radio-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Reset-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Reset-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Reset-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Reset-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-6.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-7.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Select-8.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-6.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/TestAction1.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/TestAction1_de.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/TestAction1_fr.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Textarea-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Textfield-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Textfield-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Textfield-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/User-validation.xml
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/User.properties
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/actionerror-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/actionerror-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/actionmessage-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/actionmessage-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/div-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/fielderror-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/href-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-6.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/optiontransferselect-7.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/submit-ajax-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/tooltip-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/tree-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/tree-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-1.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-10.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-11.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-2.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-3.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-4.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-5.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-6.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-7.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-8.txt
create mode 100644 trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/updownselecttag-9.txt
create mode 100644 trunk/core/src/test/resources/struts.properties
create mode 100644 trunk/core/src/test/resources/struts.xml
create mode 100644 trunk/core/src/test/resources/template/test/Component.ftl
create mode 100644 trunk/core/src/test/resources/template/test/checkbox.jsp
create mode 100644 trunk/core/src/test/resources/test.properties
create mode 100644 trunk/core/src/test/resources/testmessages.properties
create mode 100644 trunk/core/src/test/resources/testmessages2.properties
create mode 100644 trunk/core/src/test/resources/validators.xml
create mode 100644 trunk/docs/tags/ActionComponent.html
create mode 100644 trunk/docs/tags/ActionError.html
create mode 100644 trunk/docs/tags/ActionMessage.html
create mode 100644 trunk/docs/tags/Anchor.html
create mode 100644 trunk/docs/tags/AppendIterator.html
create mode 100644 trunk/docs/tags/Bean.html
create mode 100644 trunk/docs/tags/Checkbox.html
create mode 100644 trunk/docs/tags/CheckboxList.html
create mode 100644 trunk/docs/tags/ComboBox.html
create mode 100644 trunk/docs/tags/Date.html
create mode 100644 trunk/docs/tags/DatePicker.html
create mode 100644 trunk/docs/tags/Debug.html
create mode 100644 trunk/docs/tags/Div.html
create mode 100644 trunk/docs/tags/DoubleSelect.html
create mode 100644 trunk/docs/tags/Else.html
create mode 100644 trunk/docs/tags/ElseIf.html
create mode 100644 trunk/docs/tags/FieldError.html
create mode 100644 trunk/docs/tags/File.html
create mode 100644 trunk/docs/tags/Form.html
create mode 100644 trunk/docs/tags/GenericUIBean.html
create mode 100644 trunk/docs/tags/Head.html
create mode 100644 trunk/docs/tags/Hidden.html
create mode 100644 trunk/docs/tags/I18n.html
create mode 100644 trunk/docs/tags/If.html
create mode 100644 trunk/docs/tags/Include.html
create mode 100644 trunk/docs/tags/IteratorComponent.html
create mode 100644 trunk/docs/tags/Label.html
create mode 100644 trunk/docs/tags/MergeIterator.html
create mode 100644 trunk/docs/tags/OptGroup.html
create mode 100644 trunk/docs/tags/OptionTransferSelect.html
create mode 100644 trunk/docs/tags/Panel.html
create mode 100644 trunk/docs/tags/Param.html
create mode 100644 trunk/docs/tags/Password.html
create mode 100644 trunk/docs/tags/Property.html
create mode 100644 trunk/docs/tags/Push.html
create mode 100644 trunk/docs/tags/Radio.html
create mode 100644 trunk/docs/tags/Reset.html
create mode 100644 trunk/docs/tags/RichTextEditor.html
create mode 100644 trunk/docs/tags/Select.html
create mode 100644 trunk/docs/tags/Set.html
create mode 100644 trunk/docs/tags/Submit.html
create mode 100644 trunk/docs/tags/TabbedPanel.html
create mode 100644 trunk/docs/tags/Text.html
create mode 100644 trunk/docs/tags/TextArea.html
create mode 100644 trunk/docs/tags/TextField.html
create mode 100644 trunk/docs/tags/Token.html
create mode 100644 trunk/docs/tags/Tree.html
create mode 100644 trunk/docs/tags/TreeNode.html
create mode 100644 trunk/docs/tags/URL.html
create mode 100644 trunk/docs/tags/UpDownSelect.html
create mode 100644 trunk/docs/tags/WebTable.html
create mode 100644 trunk/docs/tags/index.html
create mode 100644 trunk/plugins/config-browser/pom.xml
create mode 100644 trunk/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ActionNamesAction.java
create mode 100644 trunk/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ConfigurationHelper.java
create mode 100644 trunk/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ListValidatorsAction.java
create mode 100644 trunk/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ShowConfigAction.java
create mode 100644 trunk/plugins/config-browser/src/main/java/org/apache/struts2/config_browser/ShowValidatorAction.java
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/actionNames.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/config-styles.css
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/error.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/page-footer.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/page-header.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/showConfig.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/showValidators.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/simple-error.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/tigris-macros.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/config-browser/validatorDetails.ftl
create mode 100644 trunk/plugins/config-browser/src/main/resources/struts-plugin.xml
create mode 100644 trunk/plugins/jasperreports/pom.xml
create mode 100644 trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/CompileReport.java
create mode 100644 trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportConstants.java
create mode 100644 trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/JasperReportsResult.java
create mode 100644 trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/ValueStackDataSource.java
create mode 100644 trunk/plugins/jasperreports/src/main/java/org/apache/struts2/views/jasperreports/ValueStackShadowMap.java
create mode 100644 trunk/plugins/jasperreports/src/main/resources/org/apache/struts2/views/jasperreports/package.html
create mode 100644 trunk/plugins/jasperreports/src/main/resources/struts-plugin.xml
create mode 100644 trunk/plugins/jfreechart/pom.xml
create mode 100644 trunk/plugins/jfreechart/src/main/java/org/apache/struts2/dispatcher/ChartResult.java
create mode 100644 trunk/plugins/jfreechart/src/main/resources/struts-plugin.xml
create mode 100644 trunk/plugins/jfreechart/src/test/java/org/apache/struts2/dispatcher/ChartResultTest.java
create mode 100644 trunk/plugins/jsf/pom.xml
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/ApplyRequestValuesInterceptor.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/FacesInterceptor.java
create mode 100755 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/FacesRender.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/FacesResult.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/FacesSetupInterceptor.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/FacesSupport.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/InvokeApplicationInterceptor.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/ProcessValidationsInterceptor.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/RestoreViewInterceptor.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/StrutsNavigationHandler.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/StrutsVariableResolver.java
create mode 100644 trunk/plugins/jsf/src/main/java/org/apache/struts2/jsf/UpdateModelValuesInterceptor.java
create mode 100644 trunk/plugins/jsf/src/main/resources/org/apache/struts2/jsf/package.html
create mode 100644 trunk/plugins/jsf/src/main/resources/struts-plugin.xml
create mode 100644 trunk/plugins/pell-multipart/pom.xml
create mode 100644 trunk/plugins/pell-multipart/src/main/java/org/apache/struts2/dispatcher/multipart/PellMultiPartRequest.java
create mode 100644 trunk/plugins/plexus/pom.xml
create mode 100644 trunk/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusFilter.java
create mode 100644 trunk/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusLifecycleListener.java
create mode 100644 trunk/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusObjectFactory.java
create mode 100644 trunk/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusThreadLocal.java
create mode 100644 trunk/plugins/plexus/src/main/java/org/apache/struts2/plexus/PlexusUtils.java
create mode 100644 trunk/plugins/pom.xml
create mode 100644 trunk/plugins/quickstart/pom.xml
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/Main.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/Configuration.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/JettyServer.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/Mapping.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/MultiDirClassLoader.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/MultiDirResource.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/MultiWebApplicationContext.java
create mode 100644 trunk/plugins/quickstart/src/main/java/org/apache/struts2/quickstart/QuickStart.java
create mode 100644 trunk/plugins/sitegraph/pom.xml
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/Main.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/SiteGraph.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/StrutsConfigRetriever.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/FileBasedView.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/FreeMarkerView.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/JspView.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/Target.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/VelocityView.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/entities/View.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/ActionNode.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/Graph.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/IndentWriter.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/Link.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/Render.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/SiteGraphNode.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/SubGraph.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/model/ViewNode.java
create mode 100644 trunk/plugins/sitegraph/src/main/java/org/apache/struts2/sitegraph/renderers/DOTRenderer.java
create mode 100644 trunk/plugins/sitegraph/src/test/java/org/apache/struts2/sitegraph/SiteGraphTest.java
create mode 100644 trunk/plugins/sitegraph/src/test/resources/org/apache/struts2/sitegraph/hello.jsp
create mode 100644 trunk/plugins/sitegraph/src/test/resources/org/apache/struts2/sitegraph/out.txt
create mode 100644 trunk/plugins/sitegraph/src/test/resources/org/apache/struts2/sitegraph/struts.xml
create mode 100644 trunk/plugins/sitegraph/src/test/resources/org/apache/struts2/sitegraph/tutorial/sitegraph/guess-error.ftl
create mode 100644 trunk/plugins/sitegraph/src/test/resources/org/apache/struts2/sitegraph/tutorial/sitegraph/guess-input.ftl
create mode 100644 trunk/plugins/sitegraph/src/test/resources/org/apache/struts2/sitegraph/tutorial/sitegraph/guess-success.jsp
create mode 100644 trunk/plugins/sitemesh/pom.xml
create mode 100644 trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/FreeMarkerPageFilter.java
create mode 100644 trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/TemplatePageFilter.java
create mode 100644 trunk/plugins/sitemesh/src/main/java/org/apache/struts2/sitemesh/VelocityPageFilter.java
create mode 100644 trunk/plugins/struts1/pom.xml
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/ActionFormResetInterceptor.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/ActionFormValidationInterceptor.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/DynaBeanPropertyAccessor.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/Struts1Action.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/Struts1Factory.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/WrapperActionForward.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/WrapperActionMapping.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/WrapperExceptionConfig.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/WrapperMessageResources.java
create mode 100644 trunk/plugins/struts1/src/main/java/org/apache/struts2/s1/WrapperModuleConfig.java
create mode 100644 trunk/plugins/struts1/src/main/resources/struts-plugin.xml
create mode 100644 trunk/plugins/struts1/src/test/java/org/apache/struts2/s1/DynaBeanPropertyAccessorTest.java
create mode 100644 trunk/plugins/struts1/src/test/java/org/apache/struts2/s1/Struts1FactoryTest.java
create mode 100644 trunk/plugins/struts1/src/test/resources/org/apache/struts2/s1/test-struts-factory.xml
create mode 100644 trunk/plugins/tiles/pom.xml
create mode 100644 trunk/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesListener.java
create mode 100644 trunk/plugins/tiles/src/main/java/org/apache/struts2/tiles/StrutsTilesUtilImpl.java
create mode 100644 trunk/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java
create mode 100644 trunk/plugins/tiles/src/main/resources/struts-plugin.xml
create mode 100644 trunk/pom.xml
create mode 100644 trunk/src/main/idea/project.xml
create mode 100644 trunk/src/main/idea/workspace.xml
create mode 100644 trunk/src/site/site.xml
create mode 100644 trunk/src/site/xdoc/index.xml
create mode 100755 trunk/src/site/xdoc/jxr.xml
diff --git a/trunk/all/pom.xml b/trunk/all/pom.xml
new file mode 100644
index 000000000..9ae365fae
--- /dev/null
+++ b/trunk/all/pom.xml
@@ -0,0 +1,125 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-parent
+ 2.0.1
+
+ org.apache.struts
+ struts2-all
+ jar
+ Combined Struts 2 Jar
+
+
+
+ org.codehaus.mojo
+ dependency-maven-plugin
+
+
+ unjar-deps
+ compile
+
+ unpack
+
+
+
+
+ org.apache.struts
+ struts2-core
+ ${version}
+
+
+ org.apache.struts
+ struts2-api
+ ${version}
+
+
+
+ org.apache.struts
+
+ struts2-config-browser-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-jasperreports-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-jfreechart-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-jsf-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-pell-multipart-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-plexus-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-quickstart-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-sitegraph-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-sitemesh-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-struts1-plugin
+
+ ${version}
+
+
+ org.apache.struts
+
+ struts2-tiles-plugin
+
+ ${version}
+
+
+
+ ${project.build.directory}/classes
+
+
+
+
+
+
+
diff --git a/trunk/api/pom.xml b/trunk/api/pom.xml
new file mode 100644
index 000000000..801b1425f
--- /dev/null
+++ b/trunk/api/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-parent
+ 2.0.1
+
+ org.apache.struts
+ struts2-api
+ jar
+ Struts 2 API
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+ true
+
+
+ org.easymock
+ easymock
+ test
+ 2.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ false
+
+
+
+
+
diff --git a/trunk/api/src/main/java/org/apache/struts2/Action.java b/trunk/api/src/main/java/org/apache/struts2/Action.java
new file mode 100644
index 000000000..ded7942b1
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/Action.java
@@ -0,0 +1,45 @@
+package org.apache.struts2;
+
+/**
+ * Default action interface. Provided purely for user convenience. Struts does not require actions to implement any
+ * interfaces. Actions need only implement a public, no argument method which returns {@code String}. If a user does
+ * not specify a method name, Struts defaults to {@code execute()}.
+ *
+ * For example:
+ *
+ *
+ * static import ResultNames.*;
+ *
+ * public class MyAction implements Action {
+ *
+ * public String execute() {
+ * return SUCCESS;
+ * }
+ * }
+ *
+ *
+ * is equivalent to:
+ *
+ *
+ * static import ResultNames.*;
+ *
+ * public class MyAction {
+ *
+ * public String execute() {
+ * return SUCCESS;
+ * }
+ * }
+ *
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Action {
+
+ /**
+ * Executes this action.
+ *
+ * @return result name which matches a result name from the action mapping in the configuration file. See {@link
+ * ResultNames} for common suggestions.
+ */
+ String execute();
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/MessageAware.java b/trunk/api/src/main/java/org/apache/struts2/MessageAware.java
new file mode 100644
index 000000000..70357b95e
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/MessageAware.java
@@ -0,0 +1,41 @@
+package org.apache.struts2;
+
+/**
+ * Implemented by actions which may need to record errors or messages.
+ *
+ *
+ * static import ResultNames.*;
+ *
+ * public class SetName implements MessageAware {
+ *
+ * Messages messages;
+ * String name;
+ *
+ * public String execute() {
+ * return SUCCESS;
+ * }
+ *
+ * public void setName(String name) {
+ * if ("".equals(name))
+ * messages.forField("name").addError("name.required");
+ *
+ * this.name = name;
+ * }
+ *
+ * public void setMessages(Messages messages) {
+ * this.messages = messages;
+ * }
+ * }
+ *
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface MessageAware {
+
+ /**
+ * Sets messages.
+ *
+ * @param messages messages
+ */
+ void setMessages(Messages messages);
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/Messages.java b/trunk/api/src/main/java/org/apache/struts2/Messages.java
new file mode 100644
index 000000000..d3a3d29f0
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/Messages.java
@@ -0,0 +1,196 @@
+package org.apache.struts2;
+
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * Collection of messages. Supports nesting messages by field name.
+ *
+ * Uses keys when adding instead of actual messages to decouple code from messages.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Messages {
+
+ // TODO: Use Object[] for args instead of String[].
+
+ /**
+ * Message severity.
+ */
+ public enum Severity {
+
+ /**
+ * Informational messages.
+ */
+ INFO,
+
+ /**
+ * Warning messages.
+ */
+ WARN,
+
+ /**
+ * Error messages.
+ */
+ ERROR,
+ }
+
+ /**
+ * Gets nested messages for the given field.
+ *
+ *
Supports dot notation to represent nesting. For example:
+ *
+ *
+ * messages.forField("foo").forField("bar") == messages.forField("foo.bar")
+ *
+ *
+ * @param fieldName name of the field
+ * @return nested {@code Messages} for given field name
+ */
+ Messages forField(String fieldName);
+
+ /**
+ * Gets map of field name to messages for that field.
+ *
+ * @return map of field name to {@code Messages}
+ */
+ Map forFields();
+
+ /**
+ * Adds informational message.
+ *
+ * @param key message key
+ * @see Severity.INFO
+ */
+ void addInformation(String key);
+
+ /**
+ * Adds informational message.
+ *
+ * @param key message key
+ * @param arguments message arguments
+ * @see Severity.INFO
+ */
+ void addInformation(String key, String... arguments);
+
+ /**
+ * Adds warning message.
+ *
+ * @param key message key
+ * @see Severity.WARN
+ */
+ void addWarning(String key);
+
+ /**
+ * Adds warning message.
+ *
+ * @param key message key
+ * @param arguments message arguments
+ * @see Severity.WARN
+ */
+ void addWarning(String key, String... arguments);
+
+ /**
+ * Adds error message.
+ *
+ * @param key message key
+ * @see Severity.ERROR
+ */
+ void addError(String key);
+
+ /**
+ * Adds error message.
+ *
+ * @param key message key
+ * @param arguments message arguments
+ * @see Severity.ERROR
+ */
+ void addError(String key, String... arguments);
+
+ /**
+ * Adds message.
+ *
+ * @param severity message severity
+ * @param key message key
+ */
+ void add(Severity severity, String key);
+
+ /**
+ * Adds request-scoped message.
+ *
+ * @param severity message severity
+ * @param key message key
+ * @param arguments message arguments
+ */
+ void add(Severity severity, String key, String... arguments);
+
+ /**
+ * Gets set of severities for which this {@code Messages} instance has messages. Not recursive.
+ *
+ * @return unmodifiable set of {@link Severity} sorted from least to most severe
+ */
+ Set getSeverities();
+
+ /**
+ * Gets message strings for the given severity. Not recursive.
+ *
+ * @param severity message severity
+ * @return unmodifiable list of messages
+ */
+ List forSeverity(Severity severity);
+
+ /**
+ * Gets error message strings for this {@code Messages} instance. Not recursive.
+ *
+ * @return unmodifiable list of messages
+ */
+ List getErrors();
+
+ /**
+ * Gets error message strings for this {@code Messages} instance. Not recursive.
+ *
+ * @return unmodifiable list of messages
+ */
+ List getWarnings();
+
+ /**
+ * Gets informational message strings for this {@code Messages} instance. Not recursive.
+ *
+ * @return unmodifiable list of messages
+ */
+ List getInformation();
+
+ /**
+ * Returns true if this or a nested {@code Messages} instance has error messages.
+ *
+ * @see Severity.ERROR
+ */
+ boolean hasErrors();
+
+ /**
+ * Returns true if this or a nested {@code Messages} instance has warning messages.
+ *
+ * @see Severity.WARN
+ */
+ boolean hasWarnings();
+
+ /**
+ * Returns true if this or a nested {@code Messages} instance has informational messages.
+ *
+ * @see Severity.INFO
+ */
+ boolean hasInformation();
+
+ /**
+ * Returns true if this and all nested {@code Messages} instances have no messages.
+ */
+ boolean isEmpty();
+
+ /**
+ * Returns true if this and all nested {@code Messages} instances have no messages for the given severity.
+ *
+ * @param severity message severity
+ */
+ boolean isEmpty(Severity severity);
+}
\ No newline at end of file
diff --git a/trunk/api/src/main/java/org/apache/struts2/ResultNames.java b/trunk/api/src/main/java/org/apache/struts2/ResultNames.java
new file mode 100644
index 000000000..1a93a7d89
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/ResultNames.java
@@ -0,0 +1,36 @@
+package org.apache.struts2;
+
+/**
+ * Commonly used result names returned by action methods.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public final class ResultNames {
+
+ private ResultNames() {}
+
+ /**
+ * The action executed successfully.
+ */
+ public static final String SUCCESS = "success";
+
+ /**
+ * The action requires more input, i.e. a validation error occurred.
+ */
+ public static final String INPUT = "input";
+
+ /**
+ * The action requires the user to log in before executing.
+ */
+ public static final String LOGIN = "login";
+
+ /**
+ * The action execution failed irrecoverably.
+ */
+ public static final String ERROR = "error";
+
+ /**
+ * The action executed successfully, but do not execute a result.
+ */
+ public static final String NONE = "none";
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/Validatable.java b/trunk/api/src/main/java/org/apache/struts2/Validatable.java
new file mode 100644
index 000000000..b3eef9c88
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/Validatable.java
@@ -0,0 +1,17 @@
+package org.apache.struts2;
+
+import org.apache.struts2.MessageAware;
+
+/**
+ * Implemented by actions which wish to execute some validation logic before their action method. Useful for
+ * cross-field validations.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Validatable extends MessageAware {
+
+ /**
+ * Validates input. Executes before action method.
+ */
+ public void validate();
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java b/trunk/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java
new file mode 100644
index 000000000..1dcfbe4b3
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java
@@ -0,0 +1,18 @@
+package org.apache.struts2.servlet;
+
+import java.util.Map;
+
+/**
+ * Implemented by actions which need direct access to the request parameters.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ParameterAware {
+
+ /**
+ * Sets parameters.
+ *
+ * @param parameters map of parameter name to parameter values
+ */
+ void setParameters(Map parameters);
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java b/trunk/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java
new file mode 100644
index 000000000..49e110b19
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java
@@ -0,0 +1,18 @@
+package org.apache.struts2.servlet;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Implemented by actions which need direct access to the servlet request.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ServletRequestAware {
+
+ /**
+ * Sets the servlet request.
+ *
+ * @param request servlet request.
+ */
+ void setServletRequest(HttpServletRequest request);
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java b/trunk/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java
new file mode 100644
index 000000000..427e986ac
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java
@@ -0,0 +1,18 @@
+package org.apache.struts2.servlet;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Implemented by actions which need direct access to the servlet response.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ServletResponseAware {
+
+ /**
+ * Sets the servlet response.
+ *
+ * @param response servlet response
+ */
+ void setServletResponse(HttpServletResponse response);
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/spi/ActionContext.java b/trunk/api/src/main/java/org/apache/struts2/spi/ActionContext.java
new file mode 100644
index 000000000..e45754a0f
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/spi/ActionContext.java
@@ -0,0 +1,59 @@
+package org.apache.struts2.spi;
+
+import java.lang.reflect.Method;
+
+/**
+ * Context of an action execution.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ActionContext {
+
+ /**
+ * Gets action instance.
+ */
+ Object getAction();
+
+ /**
+ * Gets action method.
+ */
+ Method getMethod();
+
+ /**
+ * Gets action name.
+ */
+ String getActionName();
+
+ /**
+ * Gets the path for the action's namespace.
+ */
+ String getNamespacePath();
+
+ /**
+ * Gets the {@link Result} instance for the action.
+ *
+ * @return {@link Result} instance or {@code null} if we don't have a result yet.
+ */
+ Result getResult();
+
+ /**
+ * Adds a result interceptor for the action. Enables executing code before and after a result, executing an
+ * alternate result, etc.
+ */
+ void addResultInterceptor(Result interceptor);
+
+ /**
+ * Gets context of action which chained to us.
+ *
+ * @return context of previous action or {@code null} if this is the first action in the chain
+ */
+ ActionContext getPrevious();
+
+ /**
+ * Gets context of action which this action chained to.
+ *
+ * @return context of next action or {@code null} if we haven't chained to another action yet or this is the last
+ * action in the chain.
+ */
+ ActionContext getNext();
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/spi/Interceptor.java b/trunk/api/src/main/java/org/apache/struts2/spi/Interceptor.java
new file mode 100644
index 000000000..16b27bc17
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/spi/Interceptor.java
@@ -0,0 +1,16 @@
+package org.apache.struts2.spi;
+
+/**
+ * Intercepts an action request.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Interceptor {
+
+ /**
+ * Intercepts an action request.
+ *
+ * @param requestContext current request context
+ */
+ String intercept(RequestContext requestContext) throws Exception;
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/spi/RequestContext.java b/trunk/api/src/main/java/org/apache/struts2/spi/RequestContext.java
new file mode 100644
index 000000000..559e8bde8
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/spi/RequestContext.java
@@ -0,0 +1,101 @@
+package org.apache.struts2.spi;
+
+import org.apache.struts2.Messages;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Request context. A single request may span multiple actions with action chaining.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface RequestContext {
+
+ /**
+ * Gets context of the currently executing action.
+ *
+ * @return current action context
+ */
+ ActionContext getActionContext();
+
+ /**
+ * Convenience method. Equivalent to {@code getActionContext().getAction()}.
+ *
+ * @return currently executing action
+ */
+ Object getAction();
+
+ /**
+ * Gets map of request parameters.
+ */
+ Map getParameterMap();
+
+ /**
+ * Gets map of request attributes.
+ */
+ Map getAttributeMap();
+
+ /**
+ * Gets map of session attributes.
+ */
+ Map getSessionMap();
+
+ /**
+ * Gets map of application (servlet context) attributes.
+ */
+ Map getApplicationMap();
+
+ /**
+ * Finds cookies with the given name,
+ */
+ List findCookiesForName(String name);
+
+ /**
+ * Gets locale.
+ */
+ Locale getLocale();
+
+ /**
+ * Sets locale. Stores the locale in the session for future requests.
+ */
+ void setLocale(Locale locale);
+
+ /**
+ * Gets messages.
+ */
+ Messages getMessages();
+
+ /**
+ * Gets the servlet request.
+ */
+ HttpServletRequest getServletRequest();
+
+ /**
+ * Gets the servlet response.
+ */
+ HttpServletResponse getServletResponse();
+
+ /**
+ * Gets the servlet context.
+ */
+ ServletContext getServletContext();
+
+ /**
+ * Gets the value stack.
+ */
+ ValueStack getValueStack();
+
+ /**
+ * Invokes the next interceptor or the action method if no more interceptors remain.
+ *
+ * @return result name
+ * @throws IllegalStateException if already invoked or called from the action
+ */
+ String proceed() throws Exception;
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java b/trunk/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java
new file mode 100644
index 000000000..2bd6797f2
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java
@@ -0,0 +1,19 @@
+package org.apache.struts2.spi;
+
+import org.apache.struts2.spi.RequestContext;
+
+/**
+ * Implemented by actions that need access to the current {@link org.apache.struts2.spi.RequestContext}. Use
+ * judiciously.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface RequestContextAware {
+
+ /**
+ * Sets {@link org.apache.struts2.spi.RequestContext}.
+ *
+ * @param requestContext
+ */
+ void setRequestContext(RequestContext requestContext);
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/spi/Result.java b/trunk/api/src/main/java/org/apache/struts2/spi/Result.java
new file mode 100644
index 000000000..6cb4ecd61
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/spi/Result.java
@@ -0,0 +1,18 @@
+package org.apache.struts2.spi;
+
+import org.apache.struts2.spi.RequestContext;
+
+/**
+ * The result of an action request. Struts creates a new {@code Result} instance for each request.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Result {
+
+ /**
+ * Executes result.
+ *
+ * @param requestContext
+ */
+ void execute(RequestContext requestContext) throws Exception;
+}
diff --git a/trunk/api/src/main/java/org/apache/struts2/spi/ValueStack.java b/trunk/api/src/main/java/org/apache/struts2/spi/ValueStack.java
new file mode 100644
index 000000000..b3cd87b00
--- /dev/null
+++ b/trunk/api/src/main/java/org/apache/struts2/spi/ValueStack.java
@@ -0,0 +1,93 @@
+package org.apache.struts2.spi;
+
+/**
+ * A central fixture of the Struts framework, the {@code ValueStack} is a stack which contains the actions
+ * which have executed in addition to other objects. Users can get and set values on the stack using expressions. The
+ * {@code ValueStack} will search down the stack starting with the most recent objects until it finds an object to
+ * which the expression can apply.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ValueStack extends Iterable {
+
+ /**
+ * Gets the top, most recent object from the stack without changing the stack.
+ *
+ * @return the top object
+ */
+ Object peek();
+
+ /**
+ * Removes the top, most recent object from the stack.
+ *
+ * @return the top object
+ */
+ Object pop();
+
+ /**
+ * Pushes an object onto the stack.
+ *
+ * @param o
+ */
+ void push(Object o);
+
+ /**
+ * Creates a shallow copy of this stack.
+ *
+ * @return a new stack which contains the same objects as this one
+ */
+ ValueStack clone();
+
+ /**
+ * Queries the stack. Starts with the top, most recent object. If the expression can apply to the object, this
+ * method returns the result of evaluating the expression. If the expression does not apply, this method moves
+ * down the stack to the next object and repeats. Returns {@code null} if the expression doesn't apply to any
+ * objects.
+ *
+ * @param expression
+ * @return the evaluation of the expression against the first applicable object in the stack
+ */
+ Object get(String expression);
+
+ /**
+ * Queries the stack and converts the result to the specified type. Starts with the top, most recent object. If
+ * the expression can apply to the object, this method returns the result of evaluating the expression converted
+ * to the specified type. If the expression does not apply, this method moves down the stack to the next object
+ * and repeats. Returns {@code null} if the expression doesn't apply to any objects.
+ *
+ * @param expression
+ * @param asType the type to convert the result to
+ * @return the evaluation of the expression against the first applicable object in the stack converted to the
+ * specified type
+ */
+ T get(String expression, Class asType);
+
+ /**
+ * Queries the stack and converts the result to a {@code String}. Starts with the top, most recent object. If the
+ * expression can apply to the object, this method returns the result of evaluating the expression converted to a
+ * {@code String}. If the expression does not apply, this method moves down the stack to the next object and
+ * repeats. Returns {@code null} if the expression doesn't apply to any objects.
+ *
+ * @param expression
+ * @return the evaluation of the expression against the first applicable object in the stack converted to a {@code
+ * String}
+ */
+ String getString(String expression);
+
+ /**
+ * Sets a value on an object from the stack. This method starts at the top, most recent object. If the expression
+ * applies to that object, this methods sets the given value on that object using the expression and converting
+ * the type as necessary. If the expression does not apply, this method moves to the next object and repeats.
+ *
+ * @param expression
+ * @param value
+ */
+ void set(String expression, Object value);
+
+ /**
+ * Returns the number of object on the stack.
+ *
+ * @return size of stack
+ */
+ int size();
+}
diff --git a/trunk/apps/blank/README.txt b/trunk/apps/blank/README.txt
new file mode 100644
index 000000000..db14cea57
--- /dev/null
+++ b/trunk/apps/blank/README.txt
@@ -0,0 +1,10 @@
+README.txt - blank
+
+This is an "empty" application that you can deploy as the basis of your own
+application.
+
+For more on getting started with Struts, see
+
+* http://cwiki.apache.org/WW/home.html
+
+----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/trunk/apps/blank/pom.xml b/trunk/apps/blank/pom.xml
new file mode 100644
index 000000000..96c0d2bf2
--- /dev/null
+++ b/trunk/apps/blank/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-apps
+ 2.0.1
+
+ org.apache.struts
+ struts2-blank
+ war
+ Blank Webapp
+
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+
+
+
+
+
+ org.mortbay.jetty
+ maven-jetty6-plugin
+
+ 10
+
+
+
+ org.apache.geronimo.specs
+ geronimo-j2ee_1.4_spec
+ 1.0
+ provided
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/java/example/ExampleSupport.java b/trunk/apps/blank/src/main/java/example/ExampleSupport.java
new file mode 100644
index 000000000..c86b1fc25
--- /dev/null
+++ b/trunk/apps/blank/src/main/java/example/ExampleSupport.java
@@ -0,0 +1,9 @@
+package example;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * Base Action class for the Tutorial package.
+ */
+public class ExampleSupport extends ActionSupport {
+}
diff --git a/trunk/apps/blank/src/main/java/example/HelloWorld.java b/trunk/apps/blank/src/main/java/example/HelloWorld.java
new file mode 100644
index 000000000..68f8e7202
--- /dev/null
+++ b/trunk/apps/blank/src/main/java/example/HelloWorld.java
@@ -0,0 +1,40 @@
+package example;
+
+/**
+ * Set welcome message.
+ */
+public class HelloWorld extends ExampleSupport {
+
+ public String execute() throws Exception {
+ setMessage(getText(MESSAGE));
+ return SUCCESS;
+ }
+
+ /**
+ * Provide default valuie for Message property.
+ */
+ public static final String MESSAGE = "HelloWorld.message";
+
+ /**
+ * Field for Message property.
+ */
+ private String message;
+
+ /**
+ * Return Message property.
+ *
+ * @return Message property
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * Set Message property.
+ *
+ * @param message Text to display on HelloWorld page.
+ */
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/trunk/apps/blank/src/main/java/example/Login.java b/trunk/apps/blank/src/main/java/example/Login.java
new file mode 100644
index 000000000..a4e6804e5
--- /dev/null
+++ b/trunk/apps/blank/src/main/java/example/Login.java
@@ -0,0 +1,38 @@
+package example;
+
+public class Login extends ExampleSupport {
+
+ public String execute() throws Exception {
+
+ if (isInvalid(getUsername())) return INPUT;
+
+ if (isInvalid(getPassword())) return INPUT;
+
+ return SUCCESS;
+ }
+
+ private boolean isInvalid(String value) {
+ return (value == null || value.length() == 0);
+ }
+
+ private String username;
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ private String password;
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+}
\ No newline at end of file
diff --git a/trunk/apps/blank/src/main/java/example/build.bat b/trunk/apps/blank/src/main/java/example/build.bat
new file mode 100644
index 000000000..a3f4edd01
--- /dev/null
+++ b/trunk/apps/blank/src/main/java/example/build.bat
@@ -0,0 +1,3 @@
+@echo off
+set CLASSPATH=..\..\..\lib\xwork-2.0-beta-1.jar
+javac *.java -d ..\..\..\classes
diff --git a/trunk/apps/blank/src/main/resources/example.xml b/trunk/apps/blank/src/main/resources/example.xml
new file mode 100644
index 000000000..5a18fe5a1
--- /dev/null
+++ b/trunk/apps/blank/src/main/resources/example.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+ /example/HelloWorld.jsp
+
+
+
+ /example/Login.jsp
+ Menu
+
+
+
+ /example/{1}.jsp
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/resources/example/Login-validation.xml b/trunk/apps/blank/src/main/resources/example/Login-validation.xml
new file mode 100644
index 000000000..d703ee7a3
--- /dev/null
+++ b/trunk/apps/blank/src/main/resources/example/Login-validation.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/resources/example/package.properties b/trunk/apps/blank/src/main/resources/example/package.properties
new file mode 100644
index 000000000..77d589daf
--- /dev/null
+++ b/trunk/apps/blank/src/main/resources/example/package.properties
@@ -0,0 +1,5 @@
+HelloWorld.message= Struts is up and running ...
+requiredstring = ${getText(fieldName)} is required.
+password = Password
+username = User Name
+Missing.message = This feature is under construction. Please try again in the next interation.
diff --git a/trunk/apps/blank/src/main/resources/example/package_es.properties b/trunk/apps/blank/src/main/resources/example/package_es.properties
new file mode 100644
index 000000000..e4740a48b
--- /dev/null
+++ b/trunk/apps/blank/src/main/resources/example/package_es.properties
@@ -0,0 +1,5 @@
+HelloWorld.message= ¡Struts está bien! ...
+requiredstring = ${getText(fieldName)} se requiere.
+password = Contraseña
+username = Nombre de Usuario
+Missing.message = ¡en obras! ¡seguir intentando!
diff --git a/trunk/apps/blank/src/main/resources/struts.properties b/trunk/apps/blank/src/main/resources/struts.properties
new file mode 100644
index 000000000..8c29875f6
--- /dev/null
+++ b/trunk/apps/blank/src/main/resources/struts.properties
@@ -0,0 +1,2 @@
+struts.devMode = true
+struts.enable.DynamicMethodInvocation = false
diff --git a/trunk/apps/blank/src/main/resources/struts.xml b/trunk/apps/blank/src/main/resources/struts.xml
new file mode 100644
index 000000000..67e1a9392
--- /dev/null
+++ b/trunk/apps/blank/src/main/resources/struts.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/WEB-INF/applicationContext.xml b/trunk/apps/blank/src/main/webapp/WEB-INF/applicationContext.xml
new file mode 100644
index 000000000..afbdcb4cc
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/WEB-INF/applicationContext.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/WEB-INF/web.xml b/trunk/apps/blank/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..c5c245a6e
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,34 @@
+
+
+
+ Struts Blank
+
+
+ struts2
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+ struts2
+ /*
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+ index.html
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/example/HelloWorld.jsp b/trunk/apps/blank/src/main/webapp/example/HelloWorld.jsp
new file mode 100644
index 000000000..938c76132
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/example/HelloWorld.jsp
@@ -0,0 +1,28 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+
+
+
+
+Languages
+
+
+
+ en
+
+ English
+
+
+
+ es
+
+ Espanol
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/example/Login.jsp b/trunk/apps/blank/src/main/webapp/example/Login.jsp
new file mode 100644
index 000000000..13d2dc4da
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/example/Login.jsp
@@ -0,0 +1,15 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Sign On
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/example/Menu.jsp b/trunk/apps/blank/src/main/webapp/example/Menu.jsp
new file mode 100644
index 000000000..a74bd2c76
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/example/Menu.jsp
@@ -0,0 +1,3 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
\ No newline at end of file
diff --git a/trunk/apps/blank/src/main/webapp/example/Missing.jsp b/trunk/apps/blank/src/main/webapp/example/Missing.jsp
new file mode 100644
index 000000000..7c01ac9be
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/example/Missing.jsp
@@ -0,0 +1,11 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+Missing Feature
+
+
+
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/example/Register.jsp b/trunk/apps/blank/src/main/webapp/example/Register.jsp
new file mode 100644
index 000000000..a74bd2c76
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/example/Register.jsp
@@ -0,0 +1,3 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
\ No newline at end of file
diff --git a/trunk/apps/blank/src/main/webapp/example/Welcome.jsp b/trunk/apps/blank/src/main/webapp/example/Welcome.jsp
new file mode 100644
index 000000000..dbd3a22e9
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/example/Welcome.jsp
@@ -0,0 +1,18 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Welcome
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+Commands
+
+ ">Sign On
+ ">Register
+
+
+
+
diff --git a/trunk/apps/blank/src/main/webapp/index.html b/trunk/apps/blank/src/main/webapp/index.html
new file mode 100644
index 000000000..8747c2483
--- /dev/null
+++ b/trunk/apps/blank/src/main/webapp/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Loading ...
+
+
diff --git a/trunk/apps/blank/src/test/java/example/ConfigTest.java b/trunk/apps/blank/src/test/java/example/ConfigTest.java
new file mode 100644
index 000000000..9b23765d3
--- /dev/null
+++ b/trunk/apps/blank/src/test/java/example/ConfigTest.java
@@ -0,0 +1,76 @@
+package example;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.config.RuntimeConfiguration;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+import com.opensymphony.xwork2.config.entities.ResultConfig;
+import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
+
+import java.util.Map;
+import java.util.List;
+
+import org.apache.struts2.StrutsTestCase;
+
+public class ConfigTest extends StrutsTestCase {
+
+ protected void assertSuccess(String result) throws Exception {
+ assertTrue("Expected a success result!",
+ ActionSupport.SUCCESS.equals(result));
+ }
+
+ protected void assertInput(String result) throws Exception {
+ assertTrue("Expected an input result!",
+ ActionSupport.INPUT.equals(result));
+ }
+
+ protected Map assertFieldErrors(ActionSupport action) throws Exception {
+ assertTrue(action.hasFieldErrors());
+ return action.getFieldErrors();
+ }
+
+ protected void assertFieldError(Map field_errors, String field_name, String error_message) {
+
+ List errors = (List) field_errors.get(field_name);
+ assertNotNull("Expected errors for " + field_name, errors);
+ assertTrue("Expected errors for " + field_name, errors.size()>0);
+ // TODO: Should be a loop
+ assertEquals(error_message,errors.get(0));
+
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ XmlConfigurationProvider c = new XmlConfigurationProvider("struts.xml");
+ configurationManager.addConfigurationProvider(c);
+ configurationManager.reload();
+ }
+
+ protected ActionConfig assertClass(String namespace, String action_name, String class_name) {
+ RuntimeConfiguration configuration = configurationManager.getConfiguration().getRuntimeConfiguration();
+ ActionConfig config = configuration.getActionConfig(namespace, action_name);
+ assertNotNull("Mssing action", config);
+ assertTrue("Wrong class name: [" + config.getClassName() + "]",
+ class_name.equals(config.getClassName()));
+ return config;
+ }
+
+ protected ActionConfig assertClass(String action_name, String class_name) {
+ return assertClass("", action_name, class_name);
+ }
+
+ protected void assertResult(ActionConfig config, String result_name, String result_value) {
+ Map results = config.getResults();
+ ResultConfig result = (ResultConfig) results.get(result_name);
+ Map params = result.getParams();
+ String value = (String) params.get("actionName");
+ if (value == null)
+ value = (String) params.get("location");
+ assertTrue("Wrong result value: [" + value + "]",
+ result_value.equals(value));
+ }
+
+ public void testConfig() throws Exception {
+ assertNotNull(configurationManager);
+ }
+
+}
diff --git a/trunk/apps/blank/src/test/java/example/HelloWorldTest.java b/trunk/apps/blank/src/test/java/example/HelloWorldTest.java
new file mode 100644
index 000000000..6933c32df
--- /dev/null
+++ b/trunk/apps/blank/src/test/java/example/HelloWorldTest.java
@@ -0,0 +1,16 @@
+package example;
+
+import com.opensymphony.xwork2.ActionSupport;
+import junit.framework.TestCase;
+
+public class HelloWorldTest extends TestCase {
+
+ public void testHelloWorld() throws Exception {
+ HelloWorld hello_world = new HelloWorld();
+ String result = hello_world.execute();
+ assertTrue("Expected a success result!",
+ ActionSupport.SUCCESS.equals(result));
+ assertTrue("Expected the default message!",
+ hello_world.getText(HelloWorld.MESSAGE).equals(hello_world.getMessage()));
+ }
+}
diff --git a/trunk/apps/blank/src/test/java/example/LoginTest.java b/trunk/apps/blank/src/test/java/example/LoginTest.java
new file mode 100644
index 000000000..1d4669d2a
--- /dev/null
+++ b/trunk/apps/blank/src/test/java/example/LoginTest.java
@@ -0,0 +1,36 @@
+package example;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.config.entities.ActionConfig;
+
+import java.util.Map;
+import java.util.Collection;
+import java.util.List;
+
+public class LoginTest extends ConfigTest {
+
+ public void FIXME_testLoginConfig() throws Exception {
+ ActionConfig config = assertClass("example", "Login!input", "example.Login");
+ assertResult(config, ActionSupport.SUCCESS, "Menu");
+ assertResult(config, ActionSupport.INPUT, "/example/Login.jsp");
+ }
+
+ public void testLoginSubmit() throws Exception {
+ Login login = new Login();
+ login.setUsername("username");
+ login.setPassword("password");
+ String result = login.execute();
+ assertSuccess(result);
+ }
+
+ // Needs access to an envinronment that includes validators
+ public void FIXME_testLoginSubmitInput() throws Exception {
+ Login login = new Login();
+ String result = login.execute();
+ assertInput(result);
+ Map errors = assertFieldErrors(login);
+ assertFieldError(errors,"username","Username is required.");
+ assertFieldError(errors,"password","Password is required.");
+ }
+
+}
diff --git a/trunk/apps/mailreader/README.txt b/trunk/apps/mailreader/README.txt
new file mode 100644
index 000000000..802aea4d4
--- /dev/null
+++ b/trunk/apps/mailreader/README.txt
@@ -0,0 +1,18 @@
+README.txt - mailreader
+
+The MailReader demonstrates a localized application with a master/child
+CRUD workflow.
+
+This rendition also demonstrates using wildcards to "normalize" an
+application.
+
+See the Sandbox for other MailReader examples using other architectures.
+
+* http://svn.apache.org/viewvc/struts/sandbox/trunk/struts2/apps/
+
+For more about the MailReader applicaton genneraly, visit Struts University.
+
+* http://www.StrutsUniversity.org/
+
+
+----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/trunk/apps/mailreader/pom.xml b/trunk/apps/mailreader/pom.xml
new file mode 100644
index 000000000..f4ca03c1a
--- /dev/null
+++ b/trunk/apps/mailreader/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-apps
+ 2.0.1
+
+ org.apache.struts
+ struts2-mailreader
+ war
+ Starter Webapp
+
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+ ${pom.groupId}
+ struts-mailreader-dao
+ 1.3.5
+
+
+
+
+
+
+
+ src/main/java
+
+ **/*.xml
+ **/*.properties
+
+
+
+
+
+ org.mortbay.jetty
+ maven-jetty6-plugin
+
+ 10
+
+
+
+ org.apache.geronimo.specs
+ geronimo-j2ee_1.4_spec
+ 1.0
+ provided
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/alternate.properties b/trunk/apps/mailreader/src/main/java/alternate.properties
new file mode 100644
index 000000000..03dbf277b
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/alternate.properties
@@ -0,0 +1,3 @@
+password=Enter your Password here ==>
+struts.logo.path=struts-power.gif
+struts.logo.alt=Powered by Struts
diff --git a/trunk/apps/mailreader/src/main/java/alternate_ja.properties b/trunk/apps/mailreader/src/main/java/alternate_ja.properties
new file mode 100644
index 000000000..981adc82c
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/alternate_ja.properties
@@ -0,0 +1 @@
+.password=\u30d1\u30b9\u30ef\u30fc\u30c9\u3092\u5165\u529b==>
diff --git a/trunk/apps/mailreader/src/main/java/applicationContext.xml b/trunk/apps/mailreader/src/main/java/applicationContext.xml
new file mode 100644
index 000000000..b98e1d8d7
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/applicationContext.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/mailreader/src/main/java/mailreader-default.xml b/trunk/apps/mailreader/src/main/java/mailreader-default.xml
new file mode 100644
index 000000000..973551b39
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader-default.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /pages/Error.jsp
+ /pages/Error.jsp
+ Login!input
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader-support.xml b/trunk/apps/mailreader/src/main/java/mailreader-support.xml
new file mode 100644
index 000000000..05091bafc
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader-support.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+ /tour.html
+
+
+
+
+ /Welcome.jsp
+
+
+
+
+ Welcome
+
+
+
+ /Login.jsp
+ Welcome
+ MainMenu
+ ChangePassword
+
+
+
+
+
+ /Registration.jsp
+ MainMenu
+
+
+
+
+
+
+
+ /Subscription.jsp
+ Registration!input
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /{1}.jsp
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/ApplicationListener.java b/trunk/apps/mailreader/src/main/java/mailreader2/ApplicationListener.java
new file mode 100644
index 000000000..4570cc43a
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/ApplicationListener.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright 1999-2002,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.
+ *
+ * $Id$
+ */
+
+package mailreader2;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUserDatabase;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import java.io.*;
+
+/**
+ * ServletContextListener that initializes and finalizes the
+ * persistent storage of User and Subscription information for the Struts
+ * Demonstration Application, using an in-memory database backed by an XML
+ * file.
+ *
+ * IMPLEMENTATION WARNING - If this web application is run
+ * from a WAR file, or in another environment where reading and writing of the
+ * web application resource is impossible, the initial contents will be copied
+ * to a file in the web application temporary directory provided by the
+ * container. This is for demonstration purposes only - you should
+ * NOT assume that files written here will survive a restart
+ * of your servlet container.
+ *
+ * This class was borrowed from the Shale Mailreader. Changes were:
+ *
+ *
+ *
+ * Path to database.xml (under classes here).
+ *
+ * Class to store protocol list (an array here).
+ *
+ *
+ *
+ * DEVELOPMENT NOTE - Another approach would be to instantiate the database via Spring.
+ *
+ */
+
+public final class ApplicationListener implements ServletContextListener {
+
+ // ------------------------------------------------------ Manifest Constants
+
+
+ /**
+ * Appication scope attribute key under which the in-memory version of
+ * our database is stored.
+ */
+ public static final String DATABASE_KEY = "database";
+
+
+ /**
+ * Application scope attribute key under which the valid selection
+ * items for the protocol property is stored.
+ */
+ public static final String PROTOCOLS_KEY = "protocols";
+
+ // ------------------------------------------------------ Instance Variables
+
+
+ /**
+ * The ServletContext for this web application.
+ */
+ private ServletContext context = null;
+
+
+ /**
+ * The {@link MemoryUserDatabase} object we construct and make available.
+ */
+ private MemoryUserDatabase database = null;
+
+
+ /**
+ * Logging output for this plug in instance.
+ */
+ private Log log = LogFactory.getLog(this.getClass());
+
+ // ------------------------------------------------------------- Properties
+
+
+ /**
+ * The web application resource path of our persistent database storage
+ * file.
+ */
+ private String pathname = "/WEB-INF/database.xml";
+
+ /**
+ * Return the application resource path to the database.
+ *
+ * @return application resource path path to the database
+ */
+ public String getPathname() {
+ return (this.pathname);
+ }
+
+ /**
+ * Set the application resource path to the database.
+ *
+ * @param pathname to the database
+ */
+ public void setPathname(String pathname) {
+ this.pathname = pathname;
+ }
+
+ // ------------------------------------------ ServletContextListener Methods
+
+
+ /**
+ * Gracefully shut down this database, releasing any resources that
+ * were allocated at initialization.
+ *
+ * @param event ServletContextEvent to process
+ */
+ public void contextDestroyed(ServletContextEvent event) {
+
+ log.info("Finalizing memory database plug in");
+
+ if (database != null) {
+ try {
+ database.close();
+ } catch (Exception e) {
+ log.error("Closing memory database", e);
+ }
+ }
+
+ context.removeAttribute(DATABASE_KEY);
+ context.removeAttribute(PROTOCOLS_KEY);
+ database = null;
+ context = null;
+
+ }
+
+
+ /**
+ * Initialize and load our initial database from persistent
+ * storage.
+ *
+ * @param event The context initialization event
+ */
+ public void contextInitialized(ServletContextEvent event) {
+
+ log.info("Initializing memory database plug in from '" +
+ pathname + "'");
+
+ // Remember our associated ServletContext
+ this.context = event.getServletContext();
+
+ // Construct a new database and make it available
+ database = new MemoryUserDatabase();
+ try {
+ String path = calculatePath();
+ if (log.isDebugEnabled()) {
+ log.debug(" Loading database from '" + path + "'");
+ }
+ database.setPathname(path);
+ database.open();
+ } catch (Exception e) {
+ log.error("Opening memory database", e);
+ throw new IllegalStateException("Cannot load database from '" +
+ pathname + "': " + e);
+ }
+ context.setAttribute(DATABASE_KEY, database);
+
+ }
+
+ // -------------------------------------------------------- Private Methods
+
+
+ /**
+ * Calculate and return an absolute pathname to the XML file to contain
+ * our persistent storage information.
+ *
+ * @throws Exception if an input/output error occurs
+ */
+ private String calculatePath() throws Exception {
+
+ // Can we access the database via file I/O?
+ String path = context.getRealPath(pathname);
+ if (path != null) {
+ return (path);
+ }
+
+ // Does a copy of this file already exist in our temporary directory
+ File dir = (File)
+ context.getAttribute("javax.servlet.context.tempdir");
+ File file = new File(dir, "struts-example-database.xml");
+ if (file.exists()) {
+ return (file.getAbsolutePath());
+ }
+
+ // Copy the static resource to a temporary file and return its path
+ InputStream is =
+ context.getResourceAsStream(pathname);
+ BufferedInputStream bis = new BufferedInputStream(is, 1024);
+ FileOutputStream os =
+ new FileOutputStream(file);
+ BufferedOutputStream bos = new BufferedOutputStream(os, 1024);
+ byte buffer[] = new byte[1024];
+ while (true) {
+ int n = bis.read(buffer);
+ if (n <= 0) {
+ break;
+ }
+ bos.write(buffer, 0, n);
+ }
+ bos.close();
+ bis.close();
+ return (file.getAbsolutePath());
+
+ }
+
+
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java b/trunk/apps/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java
new file mode 100644
index 000000000..10cc36823
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/AuthenticationInterceptor.java
@@ -0,0 +1,31 @@
+package mailreader2;
+
+import com.opensymphony.xwork2.interceptor.Interceptor;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.Action;
+import java.util.Map;
+import org.apache.struts.apps.mailreader.dao.User;
+
+public class AuthenticationInterceptor implements Interceptor {
+
+ public void destroy () {}
+
+ public void init() {}
+
+ public String intercept(ActionInvocation actionInvocation) throws Exception {
+
+ Map session = actionInvocation.getInvocationContext().getSession();
+
+ User user = (User) session.get(Constants.USER_KEY);
+
+ boolean isAuthenticated = (null!=user) && (null!=user.getDatabase());
+
+ if (!isAuthenticated) {
+ return Action.LOGIN;
+ }
+ else {
+ return actionInvocation.invoke();
+ }
+
+ }
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Constants.java b/trunk/apps/mailreader/src/main/java/mailreader2/Constants.java
new file mode 100644
index 000000000..81733bd94
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Constants.java
@@ -0,0 +1,125 @@
+/*
+ * $Id$
+ *
+ * Copyright 1999-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.
+ */
+
+package mailreader2;
+
+/**
+ * Manifest constants for the MailReader application.
+ */
+public final class Constants {
+
+ // --- Tokens ----
+
+ /**
+ * The token representing a "cancel" request.
+ */
+ public static final String CANCEL = "cancel";
+
+ /**
+ * The token representing a "create" task.
+ */
+ public static final String CREATE = "Create";
+
+ /**
+ * The application scope attribute under which our user database is
+ * stored.
+ */
+ public static final String DATABASE_KEY = "database";
+
+ /**
+ * The token representing a "edit" task.
+ */
+ public static final String DELETE = "Delete";
+
+ /**
+ * The token representing a "edit" task.
+ */
+ public static final String EDIT = "Edit";
+
+ /**
+ * The package name for this application.
+ */
+ public static final String PACKAGE = "org.apache.struts.apps.mailreader";
+
+ /**
+ * The session scope attribute under which the Subscription object
+ * currently selected by our logged-in User is stored.
+ */
+ public static final String SUBSCRIPTION_KEY = "subscription";
+
+ /**
+ * The session scope attribute under which the User object for the
+ * currently logged in user is stored.
+ */
+ public static final String USER_KEY = "user";
+
+ /**
+ * The token representing the "Host" property.
+ */
+ public static final String HOST = "host";
+
+
+ // ---- Error Messages ----
+
+ /**
+ *
+ * A static message in case message resource is not loaded.
+ *
+ */
+ public static final String ERROR_MESSAGES_NOT_LOADED =
+ "ERROR: Message resources not loaded -- check servlet container logs for error messages.";
+
+ /**
+ *
+ * A static message in case database resource is not loaded.
+ *
+ */
+ public static final String ERROR_DATABASE_NOT_LOADED =
+ "ERROR: User database not loaded -- check servlet container logs for error messages.";
+
+ /**
+ *
+ * A standard key from the message resources file, to test if it is available.
+ *
+ */
+ public static final String ERROR_DATABASE_MISSING = "error.database.missing";
+
+ /**
+ *
+ * A "magic" username to trigger an ExpiredPasswordException for testing.
+ *
+ */
+ public static final String EXPIRED_PASSWORD_EXCEPTION = "ExpiredPasswordException";
+
+ /**
+ *
+ * Name of field to associate with authentification errors.
+ *
+ */
+ public static final String PASSWORD_MISMATCH_FIELD = "password";
+
+ // ---- Log Messages ----
+
+ /**
+ *
Message to log if saving a user fails.
+ */
+ public static final String LOG_DATABASE_SAVE_ERROR =
+ " Unexpected error when saving User: ";
+
+
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Login.java b/trunk/apps/mailreader/src/main/java/mailreader2/Login.java
new file mode 100644
index 000000000..7de355718
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Login.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Copyright 2000-2004 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.
+ */
+
+package mailreader2;
+
+import org.apache.struts.apps.mailreader.dao.User;
+import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
+
+/**
+ * Validate a user login.
+ */
+public final class Login extends MailreaderSupport {
+
+ public String execute() throws ExpiredPasswordException {
+
+ User user = findUser(getUsername(), getPassword());
+
+ if (user != null) {
+ setUser(user);
+ }
+
+ if (hasErrors()) {
+ return INPUT;
+ }
+
+ return SUCCESS;
+
+ }
+
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Logon-validation.xml b/trunk/apps/mailreader/src/main/java/mailreader2/Logon-validation.xml
new file mode 100644
index 000000000..4a04c7629
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Logon-validation.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Logout.java b/trunk/apps/mailreader/src/main/java/mailreader2/Logout.java
new file mode 100644
index 000000000..1d079aebb
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Logout.java
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ *
+ * Copyright 2000-2004 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.
+ */
+
+package mailreader2;
+
+/**
+ * Log user out of the current session.
+ */
+public class Logout extends MailreaderSupport {
+
+ public String execute() {
+
+ setUser(null);
+
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.java b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.java
new file mode 100644
index 000000000..f93aeebcb
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.java
@@ -0,0 +1,559 @@
+/*
+ * $Id$
+ *
+ * Copyright 1999-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.
+ */
+
+package mailreader2;
+
+import org.apache.struts2.interceptor.ApplicationAware;
+import org.apache.struts2.interceptor.SessionAware;
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.apps.mailreader.dao.ExpiredPasswordException;
+import org.apache.struts.apps.mailreader.dao.Subscription;
+import org.apache.struts.apps.mailreader.dao.User;
+import org.apache.struts.apps.mailreader.dao.UserDatabase;
+import org.apache.struts.apps.mailreader.dao.impl.memory.MemorySubscription;
+import org.apache.struts.apps.mailreader.dao.impl.memory.MemoryUser;
+import org.springframework.beans.BeanUtils;
+
+import java.util.Map;
+
+/**
+ * Base Action for MailreaderSupport application.
+ *
+ * Note that this class does NOT implement model driven because of the way
+ * the pre-existing model is designed. The MailReader DAO includes immutable
+ * fields that can only be set on construction, and some objects do not have a
+ * default construction. One approach would be to mirror all the DAO
+ * properties on the Actions. As an alternative, this implementations uses the
+ * DAO properties where possible, and uses local Action properties only as
+ * needed. To create new objects, a blank temporary object is constructed, and
+ * the page uses a mix of local Action properties and DAO properties. When the
+ * new object is to be saved, the local Action properties are used to create
+ * the object using the DAO factory methods, the input values are copied from
+ * the temporary object, and the new object is saved. It's kludge, but it
+ * avoids creating unnecessary local properties. Pick your poison.
+ */
+public class MailreaderSupport extends ActionSupport
+ implements SessionAware, ApplicationAware {
+
+ /**
+ * Return CANCEL so apropriate result can be selected.
+ * @return "cancel" so apropriate result can be selected.
+ */
+ public String cancel() {
+ return Constants.CANCEL;
+ }
+
+
+ // ---- ApplicationAware ----
+
+ /**
+ * Field to store application context or its proxy.
+ *
+ * The application context lasts for the life of the application. A
+ * reference to the database is stored in the application context at
+ * startup.
+ */
+ private Map application;
+
+ /**
+ * Store a new application context.
+ *
+ * @param value A Map representing application state
+ */
+ public void setApplication(Map value) {
+ application = value;
+ }
+
+ /**
+ * Provide application context.
+ */
+ public Map getApplication() {
+ return application;
+ }
+
+ // ---- SessionAware ----
+
+ /**
+ * Field to store session context, or its proxy.
+ */
+ private Map session;
+
+ /**
+ * Store a new session context.
+ *
+ * @param value A Map representing session state
+ */
+ public void setSession(Map value) {
+ session = value;
+ }
+
+ /**
+ * Provide session context.
+ *
+ * @return session context
+ */
+ public Map getSession() {
+ return session;
+ }
+
+ // ---- Task property (utilized by UI) ----
+
+ /**
+ * Field to store workflow task.
+ *
+ * The Task is used to track the state of the CRUD workflows. It can be
+ * set to Constant.CREATE, Constant.EDIT, or Constant.DELETE as
+ * needed.
+ */
+ private String task = null;
+
+
+ /**
+ * Provide worklow task.
+ *
+ * @return Returns the task.
+ */
+ public String getTask() {
+ return task;
+ }
+
+ /**
+ * Store new workflow task.
+ *
+ * @param value The task to set.
+ */
+ public void setTask(String value) {
+ task = value;
+ }
+
+ // ---- Token property (utilized by UI) ----
+
+ /**
+ * Field to store double-submit guard.
+ */
+ private String token = null;
+
+
+ /**
+ * Provide Token.
+ *
+ * @return Returns the token.
+ */
+ public String getToken() {
+ return token;
+ }
+
+ /**
+ * Store new Token.
+ *
+ * @param value The token to set.
+ */
+ public void setToken(String value) {
+ token = value;
+ }
+
+
+ // ---- Host property ----
+
+ /**
+ * Field to store Subscription host.
+ *
+ * The host is an immutable property of the Subscrtion DAP object, so
+ * we need to store it locally until we are ready to create the
+ * Subscription.
+ */
+ private String host;
+
+ /**
+ * Provide tSubscription host.
+ *
+ * @return host property
+ */
+ public String getHost() {
+ return host;
+ }
+
+ /**
+ * Store new Subscription host.
+ *
+ * @param value
+ */
+ public void setHost(String value) {
+ host = value;
+ }
+
+ // ---- Password property ----
+
+ /**
+ * Field to store User password property.
+ *
+ * The User DAO object password proerty is immutable, so we store it
+ * locally until we are ready to create the object.
+ */
+ private String password = null;
+
+
+ /**
+ * Provide User password
+ *
+ * @return Returns the password.
+ */
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Store new User Password
+ *
+ * @param value The password to set.
+ */
+ public void setPassword(String value) {
+ password = value;
+ }
+
+ // ---- Password2 property (confirmation) ----
+
+ /**
+ * Field to store the User password confirmation.
+ *
+ * When a User object is created, we ask the client to enter the
+ * password twice, to help ensure the password is being typed
+ * correctly.
+ */
+ private String password2 = null;
+
+
+ /**
+ * Provide the User password confirmation.
+ *
+ * @return Returns the confirmationpassword.
+ */
+ public String getPassword2() {
+ return password2;
+ }
+
+ /**
+ * Store a new User password confirmation.
+ *
+ * @param value The confirmation password to set.
+ */
+ public void setPassword2(String value) {
+ password2 = value;
+ }
+
+ // ---- Username property ----
+
+ /**
+ * Field to store User username.
+ *
+ * The User DAO object password proerty is immutable, so we store it
+ * locally until we are ready to create the object.
+ */
+ private String username = null;
+
+
+ /**
+ * Provide User username.
+ *
+ * @return Returns the User username.
+ */
+ public String getUsername() {
+ return username;
+ }
+
+ /**
+ * Store new User username
+ *
+ * @param value The username to set.
+ */
+ public void setUsername(String value) {
+ username = value;
+ }
+
+ // ---- Database property ----
+
+ /**
+ * Provide reference to UserDatabase, or null if the database is not
+ * available.
+ *
+ * @return a reference to the UserDatabase or null if the database is not
+ * available
+ */
+ public UserDatabase getDatabase() {
+ Object db = getApplication().get(Constants.DATABASE_KEY);
+ if (db == null) {
+ this.addActionError(getText("error.database.missing"));
+ }
+ return (UserDatabase) db;
+ }
+
+ /**
+ * Store a new reference to UserDatabase
+ *
+ * @param database
+ */
+ public void setDatabase(UserDatabase database) {
+ getApplication().put(Constants.DATABASE_KEY, database);
+ }
+
+ // ---- User property ----
+
+ /**
+ * Provide reference to User object for authenticated user.
+ *
+ * @return User object for authenticated user.
+ */
+ public User getUser() {
+ return (User) getSession().get(Constants.USER_KEY);
+ }
+
+ /**
+ * Store new reference to User Object.
+ *
+ * @param user User object for authenticated user
+ */
+ public void setUser(User user) {
+ getSession().put(Constants.USER_KEY, user);
+ }
+
+ /**
+ * Obtain User object from database, or return null if the credentials
+ * are not found or invalid.
+ *
+ * @param username User username
+ * @param password User password
+ * @return User object or null if not found
+ * @throws ExpiredPasswordException
+ */
+ public User findUser(String username, String password)
+ throws ExpiredPasswordException {
+ // FIXME: Stupid testing hack to compensate for inadequate DAO layer
+ if (Constants.EXPIRED_PASSWORD_EXCEPTION.equals(username)) {
+ throw new ExpiredPasswordException(Constants.EXPIRED_PASSWORD_EXCEPTION);
+ }
+
+ User user = getDatabase().findUser(username);
+ if ((user != null) && !user.getPassword().equals(password)) {
+ user = null;
+ }
+ if (user == null) {
+ this.addFieldError(Constants.PASSWORD_MISMATCH_FIELD,
+ getText("error.password.mismatch"));
+ }
+ return user;
+ }
+
+ /**
+ * Log instance for this application.
+ */
+ protected Log log = LogFactory.getLog(Constants.PACKAGE);
+
+ /**
+ * Persist the User object, including subscriptions, to the database.
+ *
+ *
+ * @throws java.lang.Exception on database error
+ */
+ public void saveUser() throws Exception {
+ try {
+ getDatabase().save();
+ } catch (Exception e) {
+ String message = Constants.LOG_DATABASE_SAVE_ERROR + getUser()
+ .getUsername();
+ log.error(message, e);
+ throw new Exception(message, e);
+ }
+ }
+
+ public void createInputUser() {
+ User user = new MemoryUser(null, null);
+ setUser(user);
+ }
+
+ /**
+ * Verify input for creating a new user, create the user, and process
+ * the login.
+ *
+ * @return A new User and empty Errors if create succeeds, or null and
+ * Errors if create fails
+ */
+ public User createUser(String username, String password) {
+
+ UserDatabase database = getDatabase();
+ User user;
+
+ try {
+ user = database.findUser(username);
+ }
+
+ catch (ExpiredPasswordException e) {
+ user = getUser(); // Just so that it is not null
+ }
+
+ if (user != null) {
+ this.addFieldError("username", "error.username.unique");
+ return null;
+ }
+
+ return database.createUser(username);
+ }
+
+ // Since user.username is immutable, we have to use some local properties
+
+ /**
+ * Use the current User object to create a new User object, and make
+ * the new User object the authenticated user.
+ *
+ * The "current" User object is usually a temporary object being used
+ * to capture input.
+ *
+ * @param _username User username
+ * @param _password User password
+ */
+ public void copyUser(String _username, String _password) {
+ User input = getUser();
+ input.setPassword(_password);
+ User user = createUser(_username, _password);
+ if (null != user) {
+ BeanUtils.copyProperties(input,user);
+ setUser(user);
+ }
+ }
+
+ // ---- Subscription property ----
+
+ /**
+ * Obtain the cached Subscription object, if any.
+ *
+ * @return Cached Subscription object or null
+ */
+ public Subscription getSubscription() {
+ return (Subscription) getSession().get(Constants.SUBSCRIPTION_KEY);
+ }
+
+ /**
+ * Store new User Subscription.
+ *
+ * @param subscription
+ */
+ public void setSubscription(Subscription subscription) {
+ getSession().put(Constants.SUBSCRIPTION_KEY, subscription);
+ }
+
+ /**
+ * Obtain User Subscription object for the given host, or return null
+ * if not found.
+ *
+ * It would be possible for this code to throw a NullPointerException,
+ * but the ExceptionHandler in the xwork.xml will catch that for us.
+ *
+ * @return The matching Subscription or null
+ */
+ public Subscription findSubscription(String host) {
+ Subscription subscription;
+ subscription = getUser().findSubscription(host);
+ return subscription;
+ }
+
+ /**
+ * Obtain uSER Subscription for the local Host property.
+ *
+ * Usually, the host property will be set from the client request,
+ * because it was embedded in a link to the Subcription action.
+ *
+ * @return Subscription or null if not found
+ */
+ public Subscription findSubscription() {
+ return findSubscription(getHost());
+ }
+
+ /**
+ *
Provide a "temporary" User Subscription object that can be used to
+ * capture input values.
+ */
+ public void createInputSubscription() {
+ Subscription sub = new MemorySubscription(getUser(), null);
+ setSubscription(sub);
+ setHost(sub.getHost());
+ }
+
+ /**
+ * Provide new User Subscription object for the given host, or null if
+ * the host is not unique.
+ *
+ * @param host
+ * @return New User Subscription object or null
+ */
+ public Subscription createSubscription(String host) {
+
+ Subscription sub;
+
+ sub = findSubscription(host);
+
+ if (null != sub) {
+ // FIXME - localization - "error.host.unique")
+ addFieldError(Constants.HOST,"That hostname is already defined");
+ return null;
+ }
+
+ return getUser().createSubscription(host);
+ }
+
+ /**
+ * Create a new Subscription from the current Subscription object,
+ * making the new Subscription the current Subscription.
+ *
+ * Usually, the "current" Subscription is a temporary object being used
+ * to capture input values.
+ *
+ * @param host
+ */
+ public void copySubscription(String host) {
+ Subscription input = getSubscription();
+ Subscription sub = createSubscription(host);
+ if (null != sub) {
+ BeanUtils.copyProperties(input, sub);
+ setSubscription(sub);
+ setHost(sub.getHost());
+ }
+ }
+
+ /**
+ * Delete the current Subscription object from the database.
+ */
+ public void removeSubscription() {
+ getUser().removeSubscription(getSubscription());
+ getSession().remove(Constants.SUBSCRIPTION_KEY);
+ }
+
+ /**
+ * Provide MailServer Host for current User Subscription.
+ *
+ * @return MailServer Host for current User Subscription
+ */
+ public String getSubscriptionHost() {
+ Subscription sub = getSubscription();
+ if (null == sub) {
+ return null;
+ }
+ return sub.getHost();
+ }
+
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.properties b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.properties
new file mode 100644
index 000000000..6fd171ba2
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport.properties
@@ -0,0 +1,93 @@
+button.cancel=Cancel
+button.confirm=Confirm
+button.doSubmit=DO_SUBMIT
+button.doReset=DO_RESULT
+button.doCancel=org.apache.struts.taglib.html.CANCEL
+button.reset=Reset
+button.save=Save
+change.message=Your password has expired. Please ask the system administrator to change it.
+change.try=Try Again
+change.title=Password Has Expired
+database.load=Cannot load database from {0}
+error.database.missing=User database is missing, cannot validate login credentials
+error.fromAddress.format=Invalid format for From Address
+error.fromAddress.required=From Address is required
+error.fullName.required=Full Name is required
+error.host.required=Mail Server is required
+error.noSubscription=No Subscription bean in user session
+error.password.expired=Your password has expired for username {0}
+error.password.required=Password is required
+error.password2.required=Confirmation password is required
+error.password.match=Password and confirmation password must match
+error.password.mismatch=Invalid username and/or password, please try again
+error.replyToAddress.format=Invalid format for Reply To Address
+struts.messages.invalid.token=Cannot submit this form out of order
+error.type.invalid=Server Type must be 'imap' or 'pop3'
+error.type.required=Server Type is required
+error.username.required=Username is required
+error.username.unique=That username is already in use - please select another
+errors.footer=
+errors.header=Validation Error You must correct the following error(s) before proceeding:
+errors.prefix=
+errors.suffix=
+errors.ioException=I/O exception rendering error messages: {0}
+expired.password=User Password has expired for {0}
+heading.autoConnect=Auto
+heading.subscriptions=Current Subscriptions
+heading.host=Host Name
+heading.user=User Name
+heading.type=Server Type
+heading.action=Action
+index.heading=MailReader Demonstration Application Options
+index.login=Log on to the MailReader Demonstration Application
+index.registration=Register with the MailReader Demonstration Application
+index.title=MailReader Demonstration Application
+index.tour=A Walking Tour of the MailReader Demonstration Application
+linkSubscription.io=I/O Error: {0}
+linkSubscription.noSubscription=No subscription under attribute {0}
+linkUser.io=I/O Error: {0}
+linkUser.noUser=No user under attribute {0}
+login.title=MailReader Demonstration Application - Login
+mainMenu.heading=Main Menu Options for
+mainMenu.logout=Log off MailReader Demonstration Application
+mainMenu.registration=Edit your user registration profile
+mainMenu.title=MailReader Demonstration Application - Main Menu
+option.imap=IMAP Protocol
+option.pop3=POP3 Protocol
+# prompt.
+autoConnect=Auto Connect
+fromAddress=From Address
+fullName=Full Name
+mailHostname=Mail Server
+mailPassword=Mail Password
+mailServerType=Server Type
+mailUsername=Mail Username
+password=Password
+password2=(Repeat) Password
+replyToAddress=Reply To Address
+username=Username
+registration.addSubscription=Add
+registration.deleteSubscription=Delete
+registration.editSubscription=Edit
+registration.title.create=Register for the MailReader Demonstration Application
+registration.title.edit=Edit Registration for the MailReader Demonstration Application
+subscription.title.create=Create New Mail Subscription
+subscription.title.delete=Delete Existing Mail Subscription
+subscription.title.edit=Edit Existing Mail Subscription
+
+# Standard error messages for validator framework checks
+errors.required=${getText(fieldName)} is required.
+errors.minlength=${getText(fieldName)} cannot be less than {1} characters.
+errors.maxlength=${getText(fieldName)} cannot be greater than {1} characters.
+errors.invalid=${getText(fieldName)} is invalid.
+errors.byte=${getText(fieldName)} must be an byte.
+errors.short=${getText(fieldName)} must be an short.
+errors.integer=${getText(fieldName)} must be an integer.
+errors.long=${getText(fieldName)} must be an long.
+errors.float=${getText(fieldName)} must be an float.
+errors.double=${getText(fieldName)} must be an double.
+errors.date=${getText(fieldName)} is not a date.
+errors.range=${getText(fieldName)} is not in the range ${minLength} through ${maxLength}.
+errors.creditcard=${getText(fieldName)} is not a valid credit card number.
+errors.email=${getText(fieldName)} is an invalid e-mail address.
+errors.literal=${getText(fieldName)}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties
new file mode 100644
index 000000000..6bb198a05
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ja.properties
@@ -0,0 +1,89 @@
+button.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
+button.confirm=\u78ba\u8a8d
+button.reset=\u30ea\u30bb\u30c3\u30c8
+button.save=\u4fdd\u5b58
+change.message=\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F\u3002\u30B7\u30B9\u30C6\u30E0\u7BA1\u7406\u8005\u306B\u304A\u554F\u3044\u5408\u308F\u305B\u4E0B\u3055\u3044
+change.try=\u518D\u8A66\u884C
+change.title=\u30d1\u30b9\u30ef\u30fc\u30c9\u671f\u9650\u5207\u308c
+database.load= {0} \u304B\u3089\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u3092\u30ED\u30FC\u30C9\u3067\u304D\u307E\u305B\u3093
+error.database.missing=\u30E6\u30FC\u30B6\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u30ED\u30B0\u30AA\u30F3\u306E\u8A8D\u8A3C\u304C\u51FA\u6765\u307E\u305B\u3093
+error.fromAddress.format=From\u30A2\u30C9\u30EC\u30B9\u306E\u66F8\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093
+error.fromAddress.required=From\u30A2\u30C9\u30EC\u30B9\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
+error.fullName.required=\u30D5\u30EB\u30CD\u30FC\u30E0\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
+error.host.required=\u30E1\u30FC\u30EB\u30B5\u30FC\u30D0\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
+error.noSubscription=Subscription bean \u304c\u30bb\u30c3\u30b7\u30e7\u30f3\u306e\u4e2d\u306b\u3042\u308a\u307e\u305b\u3093
+error.password.expired=\u30E6\u30FC\u30B6 {0} \u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F
+error.password.required=\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u5FC5\u8981\u3067\u3059
+error.password2.required=\u30D1\u30B9\u30EF\u30FC\u30C9(\u78BA\u8A8D\u7528)\u304C\u5FC5\u8981\u3067\u3059
+error.password.match=\u30D1\u30B9\u30EF\u30FC\u30C9\u3068\u78BA\u8A8D\u7528\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u4E00\u81F4\u3057\u3066\u3044\u307E\u305B\u3093
+error.password.mismatch=\u30E6\u30FC\u30B6\u540D\u307E\u305F\u306F\u30D1\u30B9\u30EF\u30FC\u30C9\u304C\u4E0D\u6B63\u3067\u3059\u3002\u518D\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
+error.replyToAddress.format=\u8FD4\u4FE1\u30A2\u30C9\u30EC\u30B9\u306E\u66F8\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\u307E\u305B\u3093
+struts.messages.invalid.token=\u3053\u306E\u30D5\u30A9\u30FC\u30E0\u306E\u5185\u5BB9\u304C\u6B63\u3057\u304F\u306A\u3044\u305F\u3081\u9001\u4FE1\u3059\u308B\u3053\u3068\u304C\u51FA\u6765\u307E\u305B\u3093
+error.type.invalid=\u30B5\u30FC\u30D0\u30BF\u30A4\u30D7\u306F 'imap' \u304B 'pop3'\u306E\u3069\u3061\u3089\u304B\u3067\u306A\u3051\u308C\u3070\u306A\u308A\u307E\u305B\u3093
+error.type.required=\u30B5\u30FC\u30D0\u30BF\u30A4\u30D7\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
+error.username.required=\u30E6\u30FC\u30B6\u540D\u3092\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044
+error.username.unique=\u305D\u306E\u30E6\u30FC\u30B6\u540D\u306F\u65E2\u306B\u4F7F\u7528\u3055\u308C\u3066\u3044\u307E\u3059\u3002 \u5225\u306E\u30E6\u30FC\u30B6\u540D\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044
+errors.footer=
+errors.header=\u5165\u529b\u30c1\u30a7\u30c3\u30af\u30a8\u30e9\u30fc \u4ee5\u4e0b\u306e\u30a8\u30e9\u30fc\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044:
+errors.prefix=
+errors.suffix=
+errors.ioException=I/O\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f: {0}
+expired.password=\u30E6\u30FC\u30B6 {0} \u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F
+heading.autoConnect=\u81ea\u52d5\u63a5\u7d9a
+heading.subscriptions=\u73fe\u5728\u306e\u8cfc\u8aad\u60c5\u5831
+heading.host=\u30db\u30b9\u30c8\u540d
+heading.user=\u30e6\u30fc\u30b6\u540d
+heading.type=\u30b5\u30fc\u30d0\u30bf\u30a4\u30d7
+heading.action=\u64cd\u4f5c
+index.heading=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 \u30aa\u30d7\u30b7\u30e7\u30f3
+index.login=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30ed\u30b0\u30aa\u30f3
+index.registration=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e6\u30fc\u30b6\u767b\u9332
+index.title=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3(Struts 1.1-dev)
+index.tour=\u30b5\u30f3\u30d7\u30eb\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u6563\u7b56\u3059\u308b
+linkSubscription.io=I/O\u30a8\u30e9\u30fc: {0}
+linkSubscription.noSubscription=\u5c5e\u6027 {0} \u306b\u8cfc\u8aad\u60c5\u5831\u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+linkUser.io=I/O\u30a8\u30e9\u30fc: {0}
+linkUser.noUser=\u5c5e\u6027 {0} \u306b\u30e6\u30fc\u30b6\u60c5\u5831\u304c\u5b58\u5728\u3057\u307e\u305b\u3093
+login.title=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30ed\u30b0\u30aa\u30f3
+mainMenu.heading=\u30e1\u30a4\u30f3\u30e1\u30cb\u30e5\u30fc
+mainMenu.logout=MailReader \u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ed\u30b0\u30aa\u30d5
+mainMenu.registration=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u7de8\u96c6
+mainMenu.title=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e1\u30a4\u30f3\u30e1\u30cb\u30e5\u30fc
+option.imap=IMAP \u30d7\u30ed\u30c8\u30b3\u30eb
+option.pop3=POP3 \u30d7\u30ed\u30c8\u30b3\u30eb
+# prompt.
+autoConnect=\u81ea\u52d5\u63a5\u7d9a
+fromAddress=From\u30a2\u30c9\u30ec\u30b9
+fullName=\u30d5\u30eb\u30cd\u30fc\u30e0
+mailHostname=\u30e1\u30fc\u30eb\u30b5\u30fc\u30d0
+mailPassword=\u30e1\u30fc\u30eb\u30d1\u30b9\u30ef\u30fc\u30c9
+mailServerType=\u30b5\u30fc\u30d0\u30bf\u30a4\u30d7
+mailUsername=\u30e1\u30fc\u30eb\u30e6\u30fc\u30b6\u540d
+.password=\u30d1\u30b9\u30ef\u30fc\u30c9
+password2=\u30d1\u30b9\u30ef\u30fc\u30c9(\u78ba\u8a8d\u7528)
+replyToAddress=\u8fd4\u4fe1\u30a2\u30c9\u30ec\u30b9
+username=\u30e6\u30fc\u30b6\u540d
+registration.addSubscription=\u65b0\u898f\u4f5c\u6210
+registration.deleteSubscription=\u524a\u9664
+registration.editSubscription=\u7de8\u96c6
+registration.title.create=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e6\u30fc\u30b6\u767b\u9332
+registration.title.edit=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6
+subscription.title.create=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u65b0\u898f\u4f5c\u6210
+subscription.title.delete=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u524a\u9664
+subscription.title.edit=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u7de8\u96c6
+
+# Standard error messages for validator framework checks
+errors.required=${getText(fieldName)} \u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+errors.minlength=${getText(fieldName)} \u306f {1} \u6587\u5b57\u4ee5\u4e0a\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.maxlength=${getText(fieldName)} \u306f {2} \u6587\u5b57\u4ee5\u4e0b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.invalid=${getText(fieldName)} \u306f\u6b63\u3057\u304f\u3042\u308a\u307e\u305b\u3093\u3002
+errors.byte=${getText(fieldName)} \u306fbyte\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.short=${getText(fieldName)} \u306fshort\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.integer=${getText(fieldName)} \u306finteger\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.long=${getText(fieldName)} \u306flong\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.float=${getText(fieldName)} \u306ffloat\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.double=${getText(fieldName)} \u306fdouble\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.date=${getText(fieldName)} \u306f\u65e5\u4ed8\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
+errors.range=${getText(fieldName)} \u306f {1} \u304b\u3089 {2} \u306e\u9593\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.creditcard=${getText(fieldName)} \u306f\u6b63\u3057\u3044\u30af\u30ec\u30b8\u30c3\u30c8\u30ab\u30fc\u30c9\u756a\u53f7\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
+errors.email=${getText(fieldName)} \u306f\u6b63\u3057\u3044\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties
new file mode 100644
index 000000000..e7d1772f5
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/MailreaderSupport_ru.properties
@@ -0,0 +1,89 @@
+button.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
+button.confirm=\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u044c
+button.reset=\u0421\u0431\u0440\u043e\u0441\u0438\u0442\u044c
+button.save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
+change.message=Your password has expired. Please ask the system administrator to change it.
+change.try=Try Again
+change.title=Password Has Expired
+database.load=\u0411\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430 \u0438\u0437 {0}
+error.database.missing=\u041d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f - \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e.
+error.fromAddress.format=\u0412 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:' \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435.
+error.fromAddress.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0432 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:'.
+error.fullName.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f.
+error.host.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440.
+error.noSubscription=\u041f\u043e\u0434\u043f\u0438\u0441\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0432 \u0441\u0435\u0441\u0441\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+error.password.expired=Your password has expired for username {0}
+error.password.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0430\u0440\u043e\u043b\u044c.
+error.password2.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f.
+error.password.match=\u041f\u0430\u0440\u043e\u043b\u044c \u0438 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u0440\u043e\u043b\u044f \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442.
+error.password.mismatch=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u044f \u0438/\u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c - \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043d\u043e\u0432\u0430.
+error.replyToAddress.format=\u0412 \u043f\u043e\u043b\u0435 '\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430:' \u0443\u043a\u0430\u0437\u0430\u043d \u0430\u0434\u0440\u0435\u0441 \u0432 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435.
+struts.messages.invalid.token=\u042d\u0442\u0430 \u0444\u043e\u0440\u043c\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u0430 - \u043d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445.
+error.type.invalid=\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0442\u0438\u043f\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043b\u0438\u0448\u044c 'imap' \u0438\u043b\u0438 'pop3'
+error.type.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430
+error.username.required=\u0422\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+error.username.unique=\u0423\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f - \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f.
+errors.footer=
+errors.header=\u041e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043d\u0438\u0436\u0435 \u043e\u0448\u0438\u0431\u043a\u0438:
+errors.prefix=
+errors.suffix=
+errors.ioException=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0430\u0445: {0}
+expired.password=User Password has expired for {0}
+heading.autoConnect=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438
+heading.subscriptions=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438
+heading.host=\u0421\u0435\u0440\u0432\u0435\u0440
+heading.user=\u0418\u043c\u044f
+heading.type=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430
+heading.action=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+index.heading=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b'
+index.login=\u0412\u043e\u0439\u0442\u0438 \u043a\u0430\u043a \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c
+index.registration=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+index.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' (Struts 1.1-dev)
+index.tour=\u041e\u0431\u0437\u043e\u0440 \u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b'
+linkSubscription.io=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 (\u0434\u043b\u044f \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0438): {0}
+linkSubscription.noSubscription=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.
+linkUser.io=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430 (\u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f): {0}
+linkUser.noUser=\u0410\u0442\u0440\u0438\u0431\u0443\u0442 {0} \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u0438\u043b\u0438 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.
+login.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b - \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0438\u043c\u0435\u043d\u0438 \u0438 \u043f\u0430\u0440\u043e\u043b\u044f.
+mainMenu.heading=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u044e \u0434\u043b\u044f
+mainMenu.logout=\u0412\u044b\u0439\u0442\u0438
+mainMenu.registration=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
+mainMenu.title=\u0414\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 '\u0427\u0442\u0435\u043d\u0438\u0435 \u043f\u043e\u0447\u0442\u044b' - \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e
+option.imap=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b IMAP
+option.pop3=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b POP3
+# prompt.
+autoConnect=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435:
+fromAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:
+fullName=\u041f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f:
+mailHostname=\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440:
+mailPassword=\u041f\u0430\u0440\u043e\u043b\u044c \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
+mailServerType=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
+mailUsername=\u0418\u043c\u044f \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
+password=\u041f\u0430\u0440\u043e\u043b\u044c:
+password2=(\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) \u041f\u0430\u0440\u043e\u043b\u044c:
+replyToAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430:
+username=\u0418\u043c\u044f:
+registration.addSubscription=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
+registration.deleteSubscription=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+registration.editSubscription=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+registration.title.create=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+registration.title.edit=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0441\u0432\u043e\u0435\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438
+subscription.title.create=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
+subscription.title.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
+subscription.title.edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043f\u043e\u0434\u043f\u0438\u0441\u043a\u0443
+
+# Standard error messages for validator framework checks
+errors.required=${getText(fieldName)} is required.
+errors.minlength=${getText(fieldName)} cannot be less than {1} characters.
+errors.maxlength=${getText(fieldName)} cannot be greater than {2} characters.
+errors.invalid=${getText(fieldName)} is invalid.
+errors.byte=${getText(fieldName)} must be an byte.
+errors.short=${getText(fieldName)} must be an short.
+errors.integer=${getText(fieldName)} must be an integer.
+errors.long=${getText(fieldName)} must be an long.
+errors.float=${getText(fieldName)} must be an float.
+errors.double=${getText(fieldName)} must be an double.
+errors.date=${getText(fieldName)} is not a date.
+errors.range=${getText(fieldName)} is not in the range {1} through {2}.
+errors.creditcard=${getText(fieldName)} is not a valid credit card number.
+errors.email=${getText(fieldName)} is an invalid e-mail address.
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Registration-Registration!save-validation.xml b/trunk/apps/mailreader/src/main/java/mailreader2/Registration-Registration!save-validation.xml
new file mode 100644
index 000000000..689640742
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Registration-Registration!save-validation.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+ true
+ 4
+ 10
+
+
+
+
+
+
+
+
+
+
+
+ password eq password2
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Registration-validation.xml b/trunk/apps/mailreader/src/main/java/mailreader2/Registration-validation.xml
new file mode 100644
index 000000000..44d66bc19
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Registration-validation.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Registration.java b/trunk/apps/mailreader/src/main/java/mailreader2/Registration.java
new file mode 100644
index 000000000..e87fdf2c5
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Registration.java
@@ -0,0 +1,101 @@
+package mailreader2;
+
+import org.apache.struts.apps.mailreader.dao.User;
+
+
+/**
+ * Insert or update a User object to the persistent store.
+ */
+public class Registration extends MailreaderSupport {
+
+ /**
+ * Double check that there is not a valid User login.
+ *
+ * @return True if there is not a valid User login
+ */
+ private boolean isCreating() {
+ User user = getUser();
+ return (null == user) || (null == user.getDatabase());
+ }
+
+ /**
+ * Retrieve User object to edit or null if User does not exist.
+ *
+ * @return The "Success" result for this mapping
+ * @throws Exception on any error
+ */
+ public String input() throws Exception {
+
+ if (isCreating()) {
+ createInputUser();
+ setTask(Constants.CREATE);
+ } else {
+ setTask(Constants.EDIT);
+ setUsername(getUser().getUsername());
+ setPassword(getUser().getPassword());
+ setPassword2(getUser().getPassword());
+ }
+
+ return INPUT;
+ }
+
+ /**
+ * Insert or update a Registration.
+ *
+ * @return The "outcome" result code
+ * @throws Exception on any error
+ */
+ public String save() throws Exception {
+ return execute();
+ }
+
+ /**
+ * Insert or update a User object to the persistent store.
+ *
+ * If a User is not logged in, then a new User is created and
+ * automatically logged in. Otherwise, the existing User is updated.
+ *
+ * @return The "outcome" result code
+ * @throws Exception on any error
+ */
+ public String execute()
+ throws Exception {
+
+ boolean creating = Constants.CREATE.equals(getTask());
+ creating = creating && isCreating(); // trust but verify
+
+ if (creating) {
+
+ User user = findUser(getUsername(), getPassword());
+ boolean haveUser = (user != null);
+
+ if (haveUser) {
+ addActionError(getText("error.username.unique"));
+ return INPUT;
+ }
+
+ copyUser(getUsername(), getPassword());
+
+ } else {
+
+ // FIXME: Any way to call the RegisrationSave validators from here?
+ String newPassword = getPassword();
+ if (newPassword != null) {
+ String confirmPassword = getPassword2();
+ boolean matches = ((null != confirmPassword)
+ && (confirmPassword.equals(newPassword)));
+ if (matches) {
+ getUser().setPassword(newPassword);
+ } else {
+ addActionError(getText("error.password.match"));
+ return INPUT;
+ }
+ }
+ }
+
+ saveUser();
+
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Subscription-Subscription!save-validation.xml b/trunk/apps/mailreader/src/main/java/mailreader2/Subscription-Subscription!save-validation.xml
new file mode 100644
index 000000000..9f2f6d793
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Subscription-Subscription!save-validation.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Subscription-validation.xml b/trunk/apps/mailreader/src/main/java/mailreader2/Subscription-validation.xml
new file mode 100644
index 000000000..df903c25b
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Subscription-validation.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Subscription.java b/trunk/apps/mailreader/src/main/java/mailreader2/Subscription.java
new file mode 100644
index 000000000..a3f32edd3
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Subscription.java
@@ -0,0 +1,124 @@
+package mailreader2;
+
+import com.opensymphony.xwork2.Preparable;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Provide an Edit method for retrieving an existing subscription, and a
+ * Save method for updating or inserting a subscription.
+ */
+public class Subscription extends MailreaderSupport
+ implements Preparable {
+
+ /**
+ * Field to store list of MailServer types
+ */
+ private Map types = null;
+
+ /**
+ * Provide the list of MailServer types.
+ *
+ * @return List of MailServer types
+ */
+ public Map getTypes() {
+ return types;
+ }
+
+ /**
+ * Setup the MailerServer types and set the local Host property from
+ * the User Subscription (if any).
+ */
+ public void prepare() {
+
+ Map m = new LinkedHashMap();
+ m.put("imap", "IMAP Protocol");
+ m.put("pop3", "POP3 Protocol");
+ types = m;
+
+ setHost(getSubscriptionHost());
+ }
+
+ /**
+ * Setup a temporary User Subscription object to capture input
+ * values.
+ *
+ * @return INPUT
+ */
+ public String input() {
+ createInputSubscription();
+ setTask(Constants.CREATE);
+ return INPUT;
+ }
+
+ /**
+ * Load User Subscription for the local Host property.
+ *
+ * Usually, the Host is being set from the request by a link to an Edit
+ * or Delete task.
+ *
+ * @return INPUT or Error, if Subscription is not found
+ */
+ public String find() {
+
+ org.apache.struts.apps.mailreader.dao.Subscription
+ sub = findSubscription();
+
+ if (sub == null) {
+ return ERROR;
+ }
+
+ setSubscription(sub);
+
+ return INPUT;
+
+ }
+
+ /**
+ * Prepare to present a confirmation page before removing
+ * Subscription.
+ *
+ * @return INPUT or Error, if Subscription is not found
+ */
+ public String delete() {
+
+ setTask(Constants.DELETE);
+ return find();
+ }
+
+ /**
+ * Prepare to edit User Subscription.
+ *
+ * @return INPUT or Error, if Subscription is not found
+ */
+ public String edit() {
+
+ setTask(Constants.EDIT);
+ return find();
+ }
+
+ /**
+ * Examine the Task property and DELETE, CREATE, or save the User
+ * Subscription, as appropriate.
+ *
+ * @return SUCCESS
+ * @throws Exception on a database error
+ */
+ public String save() throws Exception {
+
+ if (Constants.DELETE.equals(getTask())) {
+ removeSubscription();
+ }
+
+ if (Constants.CREATE.equals(getTask())) {
+ copySubscription(getHost());
+ }
+
+ if (hasErrors()) return INPUT;
+
+ saveUser();
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/mailreader/src/main/java/mailreader2/Welcome.java b/trunk/apps/mailreader/src/main/java/mailreader2/Welcome.java
new file mode 100644
index 000000000..08ec12581
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/mailreader2/Welcome.java
@@ -0,0 +1,28 @@
+package mailreader2;
+
+/**
+ * Verify that essential resources are available.
+ */
+public class Welcome extends MailreaderSupport {
+
+ public String execute() {
+
+ // Confirm message resources loaded
+ String message = getText(Constants.ERROR_DATABASE_MISSING);
+ if (Constants.ERROR_DATABASE_MISSING.equals(message)) {
+ addActionError(Constants.ERROR_MESSAGES_NOT_LOADED);
+ }
+
+ // Confirm database loaded
+ if (null==getDatabase()) {
+ addActionError(Constants.ERROR_DATABASE_NOT_LOADED);
+ }
+
+ if (hasErrors()) {
+ return ERROR;
+ }
+ else {
+ return SUCCESS;
+ }
+ }
+}
diff --git a/trunk/apps/mailreader/src/main/java/struts.properties b/trunk/apps/mailreader/src/main/java/struts.properties
new file mode 100644
index 000000000..14f925247
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/struts.properties
@@ -0,0 +1,4 @@
+struts.objectFactory = spring
+struts.devMode = false
+struts.action.extension = do
+struts.enable.DynamicMethodInvocation = false
diff --git a/trunk/apps/mailreader/src/main/java/struts.xml b/trunk/apps/mailreader/src/main/java/struts.xml
new file mode 100644
index 000000000..fa904e2ee
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/java/struts.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/mailreader/src/main/webapp/ChangePassword.jsp b/trunk/apps/mailreader/src/main/webapp/ChangePassword.jsp
new file mode 100644
index 000000000..7743bf1b1
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/ChangePassword.jsp
@@ -0,0 +1,25 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+
+
+
+
+
+
+ ">
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/Error.jsp b/trunk/apps/mailreader/src/main/webapp/Error.jsp
new file mode 100644
index 000000000..05ab5e083
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/Error.jsp
@@ -0,0 +1,40 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+ Unexpected Error
+
+
+
+An unexpected error has occured
+
+
+ Please report this error to your system administrator
+ or appropriate technical support personnel.
+ Thank you for your cooperation.
+
+
+
+
+Error Message
+
+
+
+
+
+
+
+
+
+Technical Details
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/Footer.jsp b/trunk/apps/mailreader/src/main/webapp/Footer.jsp
new file mode 100644
index 000000000..2b3b86c48
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/Footer.jsp
@@ -0,0 +1,6 @@
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+ ">
+
diff --git a/trunk/apps/mailreader/src/main/webapp/Login.jsp b/trunk/apps/mailreader/src/main/webapp/Login.jsp
new file mode 100644
index 000000000..39ca9e049
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/Login.jsp
@@ -0,0 +1,30 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/META-INF/context.xml b/trunk/apps/mailreader/src/main/webapp/META-INF/context.xml
new file mode 100644
index 000000000..9b0b5d00f
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/META-INF/context.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/MainMenu.jsp b/trunk/apps/mailreader/src/main/webapp/MainMenu.jsp
new file mode 100644
index 000000000..4b96feb01
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/MainMenu.jsp
@@ -0,0 +1,25 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/Registration.jsp b/trunk/apps/mailreader/src/main/webapp/Registration.jsp
new file mode 100644
index 000000000..5b3ad5a34
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/Registration.jsp
@@ -0,0 +1,126 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+
+
+
+
+
+
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ">
+
+
+
+ ">
+
+
+
+
+
+
+
+
+
+ ">
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/Subscription.jsp b/trunk/apps/mailreader/src/main/webapp/Subscription.jsp
new file mode 100644
index 000000000..eb08f8d7f
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/Subscription.jsp
@@ -0,0 +1,68 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+
+
+
+
+
+
+
+
+
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/WEB-INF/database.xml b/trunk/apps/mailreader/src/main/webapp/WEB-INF/database.xml
new file mode 100644
index 000000000..5710477aa
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/WEB-INF/database.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/mailreader/src/main/webapp/WEB-INF/web.xml b/trunk/apps/mailreader/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..72571326a
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ Struts 2 Mailreader
+
+
+ contextConfigLocation
+ classpath*:applicationContext*.xml
+
+
+
+ Struts2
+
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+
+ Struts2
+ /*
+
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+
+
+ mailreader2.ApplicationListener
+
+
+
+
+ index.html
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/Welcome.jsp b/trunk/apps/mailreader/src/main/webapp/Welcome.jsp
new file mode 100644
index 000000000..a707fba4f
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/Welcome.jsp
@@ -0,0 +1,56 @@
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib uri="/struts-tags" prefix="s" %>
+
+
+
+
+
+ " rel="stylesheet"
+ type="text/css"/>
+
+
+
+
+
+
+
+Language Options
+
+
+
+ en
+
+ English
+
+
+
+ ja
+
+ Japanese
+
+
+
+ ru
+
+ Russian
+
+
+
+
+
+
+ "
+ alt=" "/>
+
+
+ ">
+
+
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/css/mailreader.css b/trunk/apps/mailreader/src/main/webapp/css/mailreader.css
new file mode 100644
index 000000000..bfc76487e
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/css/mailreader.css
@@ -0,0 +1,46 @@
+/**
+* Mailreader stylesheet
+*/
+
+body {
+ background-color: #FFFFFF;
+ color: #000000;
+ link: 000066;
+ visited: #660066;
+ active: #33CCCC;
+}
+
+A:hover {
+ color: #FF0000;
+}
+
+h1 {
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+h2 {
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+h3 {
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+h4 {
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+h5 {
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+h6 {
+ font-family: Arial, Helvetica, sans-serif;
+}
+
+font.hint {
+ font-style: italic;
+ font-size: 80%;
+ font-family: Arial, Helvetica, sans-serif;
+ text-align: left;
+}
\ No newline at end of file
diff --git a/trunk/apps/mailreader/src/main/webapp/index.html b/trunk/apps/mailreader/src/main/webapp/index.html
new file mode 100644
index 000000000..1b01b3fb3
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/index.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Loading ...
+
+
diff --git a/trunk/apps/mailreader/src/main/webapp/struts-power.gif b/trunk/apps/mailreader/src/main/webapp/struts-power.gif
new file mode 100644
index 0000000000000000000000000000000000000000..5f4e9d426757b4416401ea4f7083e08480fac11b
GIT binary patch
literal 1798
zcmchW`BPI@6vuDEPL)O!su3_ifI?i*TU(Yv*&$dosV0ITNWm*{K~O750YL!=rW9F1
zy$m9yfJ(H`DQ*NUqA()Q1qM`?yA}(SWmZ2;|SO&8U;*ykMDP<{PDP}3+Y6-&<$`Zm7%o4=4
zVur<(#e~I}#R!yG#IT66h_DE=2m;UsY0!dZs7Blz?ooyz41*a4abqE(l%a&7n4yTH
zfFz*|Aq>F`K^zp+V#;8`V9a0yjL^y;${@lZ%pjNw)F1}XKnYlogTbH;(x3&+h+Bw@
z;SowPrHI=P#zI60C72S#tqT;8#Dro@F@o&@3Ti1L6k&>BJ@5lCp&RUg{Q&|t1Zofi
zXrP2r;DEuP4bq^6IOn)D#PBd7h%*xQgRu}{OfUjpVO^krBte)U@DZE_1Aq(4!D!eP
ztOP#*6S~0;V1k8VL!bsRfQC-M0uC4q+8~X%6LHm$h8P}#i-D1_AB=?vBktqieAVBZ
zOX^R^*{r_`SF1Ogb6xKp*Q&RJJA!^gPDu~V-9*p93G1cdbAT&>d9agyl>STn-+%0<
zEyCjxHj7eKdlE$<(r_7C2sDWMcOcVg#51)CZLYa|&~&z2^tI-nuN)FMI%Mz@J1<+M
zH-<(})R~7ATLvU$1ivo0tPu00r~C`WCo42x7glwTOS=!c2Hejevjoyg-`Pt0c?Kic
z$3A{&NY$5JU2)5ef1=hzASzNI`y1(2?dHeiQq#Jr=LL4v{I@k?C%h=EbaN5^dfD~?
z(U6hj9*uOA+i`_A_*L-p?-DP`2aMT;+>RsEG9rRu~
zCg-8&zGH2gh~I?jv#RsSis@Zns+N5*HM){lw|LZZbbNBldY(u``;jJd>{dv4t;g
zHuBZOF@7yajeWC>a-6Jpy>J~V%Ru*(gP7+VGAAcH^U%8F*flV%?p
z{B3wB`qAu`b_KjjW{g5zBumCwu!70~QQ;igSHRC+p2^
zlNtqP^?g?(^F7Z_#iUO+ILz4~`-wleb&I@1D9Jy0)6lNLX2lgdSvz_*QnZIJ6
zppH;O_2Ge%&Uay(l!g3S)%Us=DuL>c1Lx+iD&W_29ClWuxR$RCZyZW|SSUGMH__@9
zd%iAh{??0s=0yeV$$RYkZ=a=(>9P*UX&t&+4!9W~iE%T27Aj+(KT0u#X)*OSEl~64}a1+>C+=E}g~yqGRj0%yfM+92a`l?u
zqbXi)U8Nb6FPI!3YO2>=lMS}+-6$Ij{4~(RFJAlkS2?yW&r+Ku+B+KE>iwCr;rs_j
z-|Li(&8dC#k=|H-S!7tONL
zLSqMdj~hCC)L0cSu-)nEJmLM^*Esvwt7{})7(H&%K4$wEWnJ%4T$)^@Nl@)$g}osj
i->jUKVkC}vXd1Hcsk_Ov^jjj=nWP5!`xzM`@BaX)9*BDY
literal 0
HcmV?d00001
diff --git a/trunk/apps/mailreader/src/main/webapp/tour.html b/trunk/apps/mailreader/src/main/webapp/tour.html
new file mode 100644
index 000000000..851ec084d
--- /dev/null
+++ b/trunk/apps/mailreader/src/main/webapp/tour.html
@@ -0,0 +1,2479 @@
+
+
+
+
+
+
+
+ A Walking Tour of the Struts 2 MailReader Application
+
+
+
+
+A Walking Tour of the Struts 2 MailReader Application
+
+
+
+ This article is meant to introduce a new user to Apache Struts 2 by
+ "walking through" a simple, but functional, application.
+ The article includes code snippets, but for the best result, you might
+ want to install the MailReader application on your own development
+ workstation and follow along.
+ Of course, the full source code to the MailReader is included in the
+ distribution.
+
+
+
+
+
+ The tour assumes the reader has a basic understanding of the Java
+ language, JavaBeans, web applications, and JavaServer Pages. For
+ background on these technologies, see the
+
+ Key Technologies Primer .
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ The premise of the MailReader is that it is the first iteration of a
+ portal application.
+ This version allows users to register and maintain a set of
+ accounts with various mail servers.
+ If completed, the application would let users read mail from their
+ accounts.
+
+
+
+ The MailReader application demonstrates registering with an application,
+ logging into an application, maintaining a master record, and maintaining
+ child records.
+ This article overviews the constructs needed to do these things,
+ including the server pages, Java classes, and configuration elements.
+
+
+
+ For more about the MailReader, including alternate implementations and a
+ set of formal Use Cases,
+ please visit the
+ Struts University MailReader site .
+
+
+
+
+
+ JAAS -
+ Note that for compatibility and ease of deployment, the MailReader
+ uses "application-based" authorization.
+ However, use of the standard Java Authentication and Authorization
+ Service (JAAS) is recommended for most applications.
+ (See the
+ Key Technologies Primer for more about
+ authentication technologies.)
+
+
+
+
+
+ The tour starts with how the initial welcome page is displayed, and
+ then steps through logging into the application and editing a subscription.
+ Please note that this not a quick peek at a "Hello World" application.
+ The tour is a rich trek into a realistic, best practices application.
+ You may need to adjust your chair and get a fresh cup of coffee.
+ Printed, the article is 29 pages long (US).
+
+
+
+
+
+ A web application, like any other web site, can specify a list of welcome pages.
+ When you open a web application without specifying a particular page, a
+ default "welcome page" is served as the response.
+
+
+
+
+
+ When a web application loads,
+ the container reads and parses the "Web Application Deployment
+ Descriptor", or "web.xml" file.
+ The framework plugs into a web application via a servlet filter.
+ Like any filter, the "struts2" filter is deployed via the "web.xml".
+
+
+
+web.xml - The Web Application Deployment Descriptor
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!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>Struts 2 MailReader</display-name>
+
+ <filter>
+ <filter-name>struts2</filter-name>
+ <filter-class>
+ org.apache.struts2.dispatcher.FilterDispatcher
+ </filter-class>
+ </filter>
+
+ <filter-mapping>
+ <filter-name>struts2 </filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+
+ <listener>
+ <listener-class>
+ org.springframework.web.context.ContextLoaderListener
+ </listener-class>
+ </listener>
+
+ <!-- Application Listener for MailReader database -->
+ <listener>
+ <listener-class>
+ mailreader2.ApplicationListener
+ </listener-class>
+ </listener>
+
+ <welcome-file-list>
+ <welcome-file>index.html</welcome-file>
+ </welcome-file-list>
+
+ </web-app>
+
+
+
+ You might note taht the web.xml configuration does not specify which file extension
+ to use with actions.
+ The default extension for Struts 2 is ".action",
+ but the extension can be changed in the struts.properties file.
+ For compatability with prior releases, the MailReader uses a .do extension for actions.
+
+
+
+struts.properties
+struts.action.extension = do
+
+
+
+ The web.xml does specify a "Welcome File List" for the application.
+ When a web address refers to a directory rather than an individual file,
+ the container consults the Welcome File List for the name of a page to
+ open by default.
+
+
+
+ However, most Struts applications do not refer to physical pages,
+ but to "virtual resources" called actions .
+ Actions specify code that we want to be run before a page
+ or other resource renders the response.
+ An accepted practice is to never link directly to server pages,
+ but only to logical action mappings.
+ By linking to actions, developers can often "rewire" an application
+ without editing the server pages.
+
+
+
+Best Practice:
+
+ "Link actions not pages."
+
+
+
+
+ The actions are listed in one or more XML configuration files,
+ the default configuration file being named "struts.xml".
+ When the application loads, the struts.xml, and any other files
+ it includes, are parsed, and the framework creates a set of
+ configuration objects.
+ Among other things, the configuration maps a request for a certain
+ page to a certain action mapping.
+
+
+
+
+ Sites can list zero or more "Welcome" pages in the web.xml.
+
+ Unless you are using Java 1.5,
+ actions cannot be specified as a Welcome page.
+ So, in the case of a Welcome page,
+ how do we follow the best practice of navigating through actions
+ rather than pages?
+
+
+
+ One solution is to use a page to "bootstrap" one of our actions.
+ We can register the usual "index.html" as the Welcome page and have it
+ redirect to a "Welcome" action.
+
+
+
+MailReader's index.html
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html><head>
+ <META HTTP-EQUIV="Refresh" CONTENT="0;URL=Welcome.do ">
+ </head>
+ <body>
+ <p>Loading ...</p>
+</body></html>
+
+
+
+ As an alternative,
+ we could also have used a JSP page that issued the redirect with a Struts tag,
+ but a plain HTML solution works as well.
+
+
+
+
+
+ When the client requests "Welcome.do", the request is passed to the "struts2"
+ FilterDispatcher (that we registered in the web.xml file).
+ The FilterDispatcher retrieves the appropriate action mapping from the
+ configuration.
+ If we just wanted to forward to the Welcome page, we could use a simple
+ configuration element.
+
+
+A simple "forward thru" action element
+<action name="Welcome ">
+ <result>/pages/Welcome.jsp </result>
+</action>
+
+
+
+ If a client asks for the Welcome action ("Welcome.do"), the "/page/Welcome.jsp"
+ page would be returned in response.
+ The client does not know, or need to know, that the physical resource is located at
+ "/pages/Welcome.jsp".
+ All the client knows is that it requested the resource "Welcome.do".
+
+
+
+ But if we peek at the configuration file for the MailReader,
+ we find a slightly more complicated XML element for the Welcome action.
+
+
+
+The Welcome action element
+<action name="Welcome" class="mailreader2.Welcome" >
+ <result>/pages/Welcome.jsp</result>
+ <interceptor-ref name="guest"/>
+ </action>
+
+
+
+ Here, the Welcome Java class executes whenever
+ someone asks for the Welcome action.
+ As it completes, the Action class can select which "result" is displayed.
+ The default result name is "success".
+ Another available result, defined at a global scope, is "error".
+
+
+
+Key concept:
+
+
+ The Action class doesn't need to know what result type is needed
+ for "success" or "error".
+ The Action can just return the logical name for a result,
+ without knowing how the result is implemented.
+
+
+
+
+
+ The net effect is that all of the result details,
+ including the paths to server pages,
+ all can be declared once in the configuration.
+ Tightly coupled implementation details are not scattered all over
+ the application.
+
+
+
+Key concept:
+
+
+ The Struts configuration lets us separate concerns and "say it once".
+ The configuration helps us "normalize" an application,
+ in much the same way we normalize a database schema.
+
+
+
+
+
+
+ OK ... but why would a Welcome Action want to choose between "success" and
+ "error"?
+
+
+
+
+
+ The MailReader application retains a list of users along with their email
+ accounts.
+ The application stores this information in a database.
+ If the application can't connect to the database, the application can't do
+ its job.
+ So before displaying the Welcome page , the Welcome
+ class checks to see if the database is available.
+
+
+
+ The MailReader is also an internationalized application.
+ So, the Welcome Action class checks to see if the message resources are
+ available too.
+ If both resources are available, the class passes back the "success" token.
+ Otherwise, the class passes back the "error" token,
+ so that the appropriate messages can be displayed.
+
+
+
+The Welcome Action class
+package mailreader2;
+public class Welcome extends MailreaderSupport {
+
+ public String execute() {
+
+ // Confirm message resources loaded
+ String message = getText(Constants.ERROR_DATABASE_MISSING);
+ if (Constants.ERROR_DATABASE_MISSING.equals(message)) {
+ addActionError(Constants.ERROR_MESSAGES_NOT_LOADED);
+ }
+
+ // Confirm database loaded
+ if (null==getDatabase()) {
+ addActionError(Constants.ERROR_DATABASE_NOT_LOADED);
+ }
+
+ if (hasErrors()) {
+ return ERROR;
+ }
+ else {
+ return SUCCESS;
+ }
+ }
+}
+
+
+
+ Several common result names are predefined,
+ including ERROR, SUCCESS, LOGIN, NONE, and INPUT,
+ so that these tokens can be used consistently across Struts 2 applications.
+
+
+
+
+
+
+ As mentioned, "error" is defined in a global scope.
+ Other actions may have trouble connecting to the database later,
+ or other unexpected errors may occur.
+ The MailReader defines the "error" result as a Global Result,
+ so that any action can use it.
+
+
+
+MailReader's global-result element
+ <global-results>
+ <result name="error" >/pages/Error.jsp </result>
+ <result name="invalid.token">/pages/Error.jsp</result>
+ <result name="login" type="redirect-action">Login!input</result>
+</global-results>
+
+
+
+ Of course, if an individual action mapping defines its own "error" result type,
+ the local result would be used instead.
+
+
+
+
+
+ The database is exposed as an object stored in application scope.
+ The database object is based on an interface.
+ Different implementations of the database could be loaded without changing
+ the rest of the application.
+ But how is the database object loaded in the first place?
+
+
+
+ The database is created by a custom Listener that we configured in the "web.xml".
+
+
+
+mailreader2.ApplicationListener
+ <listener>
+ <listener-class>
+ mailreader2.ApplicationListener
+ </listener-class>
+</listener>
+
+
+
+ By default, our ApplicationListener loads a MemoryDatabase
+ implementation of the UserDatabase.
+ MemoryDatabase stores the database content as a XML document,
+ which is parsed and loaded as a set of nested hashtables.
+ The outer table is the list of user objects, each of which has its own
+ inner hashtable of subscriptions.
+ When you register, a user object is stored in this hashtable.
+ When you login, the user object is stored within the session context.
+
+
+
+ The database comes seeded with a sample user.
+ If you check the "database.xml" file under "/src/main/resources",
+ you'll see the sample user described in XML.
+
+
+
+The "seed" user element from the MailReader database.xml
+<user username="user " fromAddress="John.User@somewhere.com"
+ fullName="John Q. User " password="pass ">
+ <subscription host="mail.hotmail.com" autoConnect="false"
+ password="bar" type="pop3" username="user1234">
+ </subscription>
+ <subscription host="mail.yahoo.com " autoConnect="false" password="foo"
+ type="imap" username="jquser">
+ </subscription>
+</user>
+
+
+
+ The "seed" user element creates a registration record for "John Q. User",
+ with the subscription detail for his hotmail and yahoo accounts.
+
+
+
+
+
+ As mentioned, MailReader is an internationalized application.
+ In Struts 2, message resources are associated with the Action class being processed.
+ If we check the source, we find a language resource bundle named
+ MailreaderSupport.
+ MailreaderSupport is our base class for all the MailReader Actions.
+ Since all of our Actions extend MailreaderSupport,
+ all of our Actions can use the same resource bundle.
+
+
+
+Message Resource entries used by the Welcome page
+index.heading= MailReader Application Options
+index.login= Log on to the MailReader Application
+index.registration= Register with the MailReader Application
+index.title= MailReader Demonstration Application
+index.tour= A Walking Tour of the MailReader Demonstration Application
+
+
+
+ If you change a message in the resource, and then rebuild and reload the
+ application, the change will appear throughout the application.
+ If you provide message resources for additional locales, you can
+ localize your application.
+ The MailReader provides resources for English, Russian, and Japanese.
+
+
+
+
+
+ After confirming that the necessary resources exist, the Welcome action
+ forwards to the Welcome page.
+
+
+Welcome.jsp
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <title><s:text name="index.title"/> </title>
+ <link href="<s:url value="/css/mailreader.css"/> " rel="stylesheet"
+ type="text/css"/>
+ </head>
+
+ <body>
+ <h3><s:text name="index.heading"/></h3>
+
+ <ul>
+ <li><a href="<s:url action="Registration!input"/>"><s:text
+ name="index.registration"/></a></li>
+ <li><a href="<s:url action="Login!input"/>"><s:text
+ name="index.login"/></a></li>
+ </ul>
+
+ <h3>Language Options</h3>
+ <ul>
+ <li>
+ <s:url id="en" action="Welcome">
+ <s:param name="request_locale">en</s:param>
+ </s:url>
+ <s:a href="%{en}">English</s:a>
+ </li>
+ <li>
+ <s:url id="ja" action="Welcome">
+ <s:param name="request_locale">ja</s:param>
+ </s:url>
+ <s:a href="%{ja}">Japanese</s:a>
+ </li>
+ <li>
+ <s:url id="ru" action="Welcome">
+ <s:param name="request_locale">ru</s:param>
+ </s:url>
+ <s:a href="%{ru}">Russian</s:a>
+ </li>
+ </ul>
+
+ <hr />
+
+ <p><s:i18n name="alternate">
+ <img src="<s:text name="struts.logo.path"/>"
+ alt="<s:text name="struts.logo.alt"/>"/>
+ </s:i18n> </p>
+
+ <p><a href="<s:url action="Tour" />"><s:text name="index.tour"/></a></p>
+
+ </body>
+</html>
+
+
+
+ At the top of the Welcome page, there are several directives that load the
+ Struts 2 tag libraries.
+ These are just the usual red tape that goes with any JSP file.
+ The rest of the page utilizes three Struts JSP tags:
+ "text", "url", and "i18n".
+
+
+
+ (We use the tag prefix "s:" in the Struts 2 MailReader application,
+ but you can use whatever prefix you like in your applications.)
+
+
+
+ The text tag inserts a message from an
+ application's default resource bundle.
+ If the framework's locale setting is changed for a user,
+ the text tag will render messages from the new locale's resource
+ bundle instead.
+
+
+
+ The url tag can render a reference to an
+ action or any other web resource,
+ applying "URL encoding" to the hyperlinks as needed.
+ Java's URL encoding feature lets your application maintain client state
+ without requiring cookies.
+
+
+
+Tip:
+
+
+ Cookies -
+ If you turn cookies off in your browser, and then reload your browser
+ and this page,
+ you will see the links with the Java session id information attached.
+ (If you are using Internet Explorer and try this,
+ be sure you reset cookies for the appropriate security zone,
+ and that you disallow "per-session" cookies.)
+
+
+
+
+
+ The i18n tag provides access to multiple resource bundles.
+ The MailReader application uses a second set of message resources for
+ non-text elements.
+ When these are needed, we use the "i18n" tag to specify a different bundle.
+
+
+
+ The alternate bundle is stored in the {{/src/main/resources}} folder,
+ so that it ends up under "classes", which is on the application's class path.
+
+
+
+ In the span of a single request for the Welcome page, the framework has done
+ quite a bit already:
+
+
+
+
+ Confirmed that required resources were loaded during initialization.
+
+
+
+ Written all the page headings and labels from internationalized
+ message resources.
+
+
+
+ Automatically URL-encoded paths as needed.
+
+
+
+
+ When rendered, the Welcome page lists two menu options:
+ one to register with the application and one to log on (if you have
+ already registered).
+ Let's follow the Login link first.
+
+
+
+
+
+ If you choose the Login link, and all goes well, the Login action forwards
+ control to the Login page.
+
+
+
+
+
+ The Login page displays a form that accepts a username and password.
+ You can use the default username and password to login
+ (user and pass ), if
+ you like. Try omitting or misspelling the username and password in
+ various combinations to see how the application reacts.
+ Note that both the username and password are case sensitive.
+
+
+
+Login.jsp
+<%@ page contentType="text/html; charset=UTF-8" %>
+ <%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title><s:text name="login.title"/></title>
+ <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
+ type="text/css"/>
+ </head>
+ <body onLoad="self.focus();document.Login.username.focus()">
+ <s:actionerror/>
+ <s:form action="Login" validate="true">
+ <s:textfield label="%{getText('username')}" name="username"/>
+ <s:password label="%{getText('password')}" name="password"/>
+ <s:submit value="%{getText('button.save')}"/>
+ <s:reset value="%{getText('button.reset')}"/>
+ <s:submit action="Login!cancel" onclick="form.onsubmit=null"
+ value="%{getText('button.cancel')}"/>
+ </s:form>
+ <jsp:include page="Footer.jsp"/>
+ </body>
+</html>
+
+
+
+ We already saw some of the tags used by the Login page on the Welcome page.
+ Let's focus on the new tags.
+
+
+
+ The first new tag on the Login page is actionerrors .
+ Most of the possible validation errors are related to a single field.
+ If you don't enter a username,
+ the framework can place an error message near the tag prompting you to
+ enter a username.
+ But some messages are not related to a single field.
+ For example, the database might be down.
+ If the action returns an "Action Error", as opposed to a "Field Error",
+ the messages are rendered in place of the "actionerror" tag.
+ The text for the validation errors, whether they are Action Errors or
+ Field Errors, can be specified in the resource bundle,
+ making the messages easy to manage and localize.
+
+
+
+ The second new tag is form .
+ This tag renders a HTML form tag.
+ The "validate=true" setting enables client-side validation,
+ so that the form can be validated with JavaScript before being sent
+ back to the server.
+ The framework will still validate the form again, just to be sure, but the
+ client-side validation can save a few round-trips to the server.
+
+
+
+ Within the form tag,
+ we see four more new tags: "textfield", "password", "submit",
+ and "reset". We also see a second usage of "submit" that utilizes an
+ "action" attribute.
+
+
+
+ When we place a control on a form, we usually need to code a set of
+ HTML tags to do everything we want to do.
+ Most often, we do not just want a plain "input type=text" tag.
+ We want the input field to have a label too, and maybe even
+ a tooltip. And, of course, a place to print a message
+ should invalid data be entered.
+
+
+
+ The Struts Tags support templates and themes so that a set of HTML tags can be
+ rendered from a single Struts Tag. For example, the single tag
+
+
+
+ <s:textfield label="%{getText('username')}" name="username"/>
+
+
+
+ generates a wad of HTML markup.
+
+
+
+<tr>
+ <td class="tdLabel">
+ <label for="Login_username" class="label">Username:</label>
+ </td>
+ <td>
+ <input type="text" name="username" value="" id="Login_username"/>
+ </td>
+</tr>
+
+
+
+ If for some reason you don't like the markup generated by a Struts Tag,
+ it's each to change.
+ Each tag is driven by a template that can be updated on a tag-by-tag basis.
+ For example,
+ here is the default template that generates the markup for the ActionErrors tag:
+
+
+
+<#if (actionErrors?exists && actionErrors?size > 0)>
+ <ul>
+ <#list actionErrors as error>
+ <li><span class="errorMessage">${error}</span></li>
+ </#list>
+ </ul>
+</#if>
+
+
+
+ If you wanted ActionErrors displayed in a table instead of a list,
+ you could edit a copy of this file, save it as a file named
+ "template/simple/actionerror.ftl",
+ and place this one file at the base of your application's classpath.
+
+
+
+<#if (actionErrors?exists && actionErrors?size > 0)>
+ <table>
+ <#list actionErrors as error>
+ <tr><td> <span class="errorMessage">${error}</span></td></tr>
+ </#list>
+ </table>
+</#if>
+
+
+
+ Under the covers, the framework uses
+ Freemarker
+ for its standard templating language.
+ FreeMarker is similar to
+ Velocity ,
+ but it offers better error reporting and some additional features.
+ If you prefer, Velocity and JSP templates can also be used to create your own tags.
+
+
+
+ The password tag renders a "input type=password"
+ tag, along with the usual template/theme markup.
+ By default, the password tag will not retain input if the submit fails.
+ If the username is wrong,
+ the client will have to enter the password again too.
+ (If you did want to retain the password when validation fails,
+ you can set the tag's "showPassword" property to true.)
+
+
+
+ Unsurprisingly, the submit and reset tags
+ render buttons of the corresponding types.
+
+
+
+ The second submit button is more interesting.
+
+
+ <s:submit action="Login!cancel" onclick="form.onsubmit=null"
+ value="%{getText('button.cancel')}"/>
+
+
+
+ Here we are creating the Cancel button for the form.
+ The button's attribute action="Login! cancel"
+ tells the framework to submit to the Login's "cancel" method
+ instead of the usual "execute" method.
+ The onclick="form.onsubmit=null" script defeats client-side validation.
+ On the server side, "cancel" is on a special list of methods that bypass validation,
+ so the request will go directly to the Action's cancel method.
+ Another entry on the special-case list is the "input" method.
+
+
+
+Tip:
+
+
+ The Struts Tags have options and capabilities beyond what we have shown here.
+ For more see, the
+ Struts Tag documentation.
+
+
+
+
+
+ OK, but how do the tags know that both of these fields are required?
+ How do they know what message to display when the fields are empty?
+
+
+
+ For the answers, we need to look at another flavor of configuration file:
+ the "validation" file.
+
+
+
+
+
+ While it is not hard to code data-entry validation into an Action class,
+ the framework provides an even easier way to validate input.
+
+
+
+ The validation framework is configured through another XML document, the
+ Login-validation.xml .
+
+
+
+Validation file for Login Action
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <field name="username ">
+ <field-validator type="requiredstring ">
+ <message key="error.username.required "/>
+ </field-validator>
+ </field>
+ <field name="password ">
+ <field-validator type="requiredstring ">
+ <message key="error.password.required "/>
+ </field-validator>
+ </field>
+</validators>
+
+
+
+
+ You may note that the DTD refers to "XWork".
+
+ Open Symphony XWork
+ is a generic command-pattern framework that can be used outside of a
+ web environment. In practice, Struts 2 is a web-based extension of the
+ XWork framework.
+
+
+
+ The field elements correspond to the ActionForm properties.
+ The username and password field elements
+ say that each field depends on the "requiredstring" validator.
+ If the username is blank or absent, validation will fail and an error
+ message is generated.
+ The messages would be based on the "error.username.required" or
+ "error.password.required" message templates, from the resource bundle.
+
+
+
+
+
+
+
+ If validation passes, the framework invokes the "execute" method of the Login Action.
+ The actual Login Action is brief, since most of the functionality derives
+ from the base class, MailreaderSupport .
+
+
+
+Login.java
+package mailreader2;
+import org.apache.struts.apps.mailreader.dao.User;
+public final class Login extends MailreaderSupport {
+public String execute() throws ExpiredPasswordException {
+ User user = findUser(getUsername(), getPassword());
+ if (user != null) {
+ setUser(user);
+ }
+ if (hasErrors() ) {
+ return INPUT;
+ }
+ return SUCCESS;
+ }
+}
+
+
+
+ Login lays out what we do to authenticate a user.
+ We try to find the user using the credentials provided.
+ If the user is found, we cache a reference.
+ If the user is not found, we return "input" so the client can try again.
+ Otherwise, we return "success", so that the client can access the rest of the application.
+
+
+
+
+
+ Let's look at the relevant properties and methods from MailreaderSupport
+ and another base class, ActionSupport , namely
+ "getUsername", "getPassword", "findUser", "setUser", and "hasErrors".
+
+
+
+ The framework lets you define
+ JavaBean properties
+ directly on the Action.
+ Any JavaBean property can be used, including rich objects.
+ When a request comes in,
+ any public properties on the Action class are matched with the request parameters.
+ When the names match, the request parameter value is set to the JavaBean property.
+ The framework will make its best effort to convert the data,
+ and, if necessary, it will report any conversion errors.
+
+
+
+ The Username and Password properties are nothing fancy,
+ just standard JavaBean properties.
+
+
+
+MailreaderSupport.getUsername() and getPassword()
+private String username = null;
+public String getUsername() {
+ return this.username;
+}
+public void setUsername(String username) {
+ this.username = username;
+}
+
+private String password = null;
+public String getPassword() {
+ return this.password;
+}
+public void setPassword(String password) {
+ this.password = password;
+}
+
+
+
+ We use these properties to capture the client's credentials,
+ and pass them to the more interesting findUser method.
+
+
+
+MailreaderSupport.findUser
+public User findUser (String username, String password)
+ throws ExpiredPasswordException {
+ User user = getDatabase().findUser(username) ;
+ if ((user != null) && !user.getPassword().equals(password)) {
+ user = null;
+ }
+ if (user == null) {
+ this.addFieldError ("password", getText("error.password.mismatch"));
+ }
+ return user;
+}
+
+
+
+ The "findUser" method dips into the MailReader Data Access Object layer,
+ which is represented by the Database property.
+ The code for the DAO layer is maintained as a separate component.
+ The MailReader application imports the DAO JAR,
+ but it is not responsible for maintaining any of the DAO source.
+ Keeping the data access layer at "arms-length" is a very good habit.
+ It encourages a style of development where the data access layer
+ can be tested and developed independently of a specific end-user application.
+ In fact, there are several renditions of the MailReader application,
+ all which share the same MailReader DAO JAR!
+
+
+
+Best Practice:
+
+
+ "Strongly separate data access and business logic from the rest of
+ the application."
+
+
+
+
+
+ When "findUser" returns,
+ the Login Action looks to see if a valid (non-null) User object is returned.
+ A valid User is passed to the User property .
+ Although it is still a JavaBean property,
+ the User property is not implemented in quite the same way as Username and Password.
+
+
+
+MailreaderSupport.setUser
+public User getUser() {
+ return (User) getSession().get(Constants.USER_KEY) ;
+}
+public void setUser(User user) {
+ getSession().put(Constants.USER_KEY, user);
+}
+
+
+
+ Instead of using a field to store the property value,
+ "setUser" passes it to a Session property.
+
+
+
+MailreaderSupport.getSession() and setSession()
+private Map session;
+public Map getSession() {
+ return session;
+
+public void setSession(Map value) {
+ session = value;
+}
+
+
+
+ To look at the MailreaderSupport class,
+ you would think the Session property is a plain-old Map.
+ In fact,
+ the Session property is an adapter that is backed by the servlet session object at runtime.
+ The MailreaderSupport class doesn't need to know that though.
+ It can treat Session like any other Map.
+ We can also test the MailreaderSupport class by passing it some other implementation of
+ Map, running the test,
+ and then looking to see what changes MailreaderSupport made to our "mock" Session object.
+
+
+
+ But, when MailreaderSupport is running inside a web application,
+ how does it acquire a reference to the servlet session?
+
+
+
+ Good question. If you were to look at just the MailreaderSupport class,
+ you would not see a single line of code that sets the session property.
+ But, yet, when we run the class, the session property is not null.
+ Hmmm.
+
+
+
+ The magic that provides the Session property a runtime value is called
+ "dependency injection".
+ The MailreaderSupport class implements a interface called SessionAware .
+ SessionAware is bundled with the framework,
+ and it defines a setter for the Session property.
+
+
+
+ public void setSession (Map session);
+
+
+
+ Also bundled with the framework is an object called the
+ ServletConfigInterceptor .
+ If the ServletConfigInterceptor sees that an Action implements the SessionAware interface,
+ it automatically set the session property.
+
+
+if (action instanceof SessionAware) {
+ ((SessionAware) action).setSession(context.getSession());
+}
+
+
+ The framework uses these "Interceptor" classes to create a front controller
+ for each action an application defines.
+ Each Interceptor can peek at the request before an Action class is invoked,
+ and then again after the Action class is invoked.
+ (If you have worked with Servlet
+ Filters ,
+ you will recognize this pattern.
+ But, unlike Filters, Interceptors are not tied to HTTP.
+ Interceptors can be tested and developed outside of a web application.)
+
+
+
+ You can use the same set of Interceptors for all your actions,
+ or define a special set of Interceptors for any given action,
+ or define different sets of Interceptors to use with different types of actions.
+ The framework comes with a default set of Interceptors,
+ that it will use when another set is not specified,
+ but you can designate your own default Interceptor set (or "stack")
+ in the Struts configuration.
+
+
+
+ Many Interceptors provide a utility or helper functions,
+ like setting the session property.
+ Others, like the ValidationInterceptor ,
+ can change the workflow of an action.
+ Interceptors are key feature of the framework,
+ and we will see a few more on the tour.
+
+
+
+ If a valid User is not found, or the password doesn't match,
+ the "findUser" method invokes the addFieldError method to note the
+ problem.
+ When "findUser" returns, the Login Action checks for errors,
+ and then it returns either INPUT or SUCCESS.
+
+
+
+ The "addFieldError" method is provided by the ActionSupport class,
+ which is bundled with the framework.
+ The constants for INPUT and SUCCESS are also provided by ActionSupport.
+ While the ActionSupport class provides many useful utilities,
+ you are not required to use it as a base class.
+ Any Java class can be used as an Action, if you like.
+
+
+
+ It is a good practice to provide a base class with utilities
+ that can be shared by an application's Action classes.
+ The framework does this with ActionSupport,
+ and the MailReader application does the same with the MailreaderSupport class.
+
+
+
+Best Practice:
+
+ "Use a base class to define common functionality."
+
+
+
+
+ But, what happens if Login returns INPUT instead of SUCCESS.
+ How does the framework know what to do next?
+
+
+
+ To answer that question,
+ we need to turn back to the Struts configuration
+ and look at how Login is declared.
+
+
+
+
+
+
+ The Login action element outlines how the Login workflow operates,
+ including what to do when the Action returns "input",
+ or the default result name "success".
+
+
+
+mailreader-support.xml Login
+<action name="Login!* " method="{1}" class="mailreader2.Login">
+ <result name="input ">/pages/Login.jsp</result>
+ <result name="cancel " type="redirect-action">Welcome</result>
+ <result type="redirect-action">MainMenu</result>
+ <result name="expired " type="chain">ChangePassword</result>
+ <exception-mapping
+ exception="org.apache.struts.apps.mailreader.dao.ExpiredPasswordException"
+ result="expired "/>
+ <interceptor-ref name="guest "/>
+</action>
+
+
+
+ You might notice that the name of the Login action element is not "Login"
+ but "Login!* ".
+ The asterisk is a special "wildcard" notation that tells the framework to match any series
+ of character at this point.
+ In the method attribute,
+ the "{1}" notation indicates that framework should substitute whatever characters match
+ the asterisk at runtime.
+ When we cite actions like "Login!cancel" or "Login!input",
+ the framework matches "cancel" or "input" with the wildcard and fills in the blanks.
+
+
+
+ The "trailing bang" notation was hardwired into WebWork 2.
+ To provide backward compatibility,
+ the notation is supported by Struts 2.0.
+ If you prefer to use wildcards to emulate the same notation,
+ as the Mailreader does,
+ you should disable the old notation in the Struts properties file.
+
+
+
+struts.properties
+struts.enable.DynamicMethodInvocation = false
+
+
+
+ Using wildcards with a exclamation point (or "bang") is not the only way we can use
+ wilcards to invoke methods.
+ If we wanted to use actions like "inputLogin",
+ we could move the asterisk and use an action name like "*Login".
+
+
+
+ Within the Login action element, the first result element is named "input".
+ If validation or authentification fail,
+ the Action class will return "input" and the framework will transfer control to the
+ "Login.jsp" page.
+
+
+
+ The second result element is named cancel .
+ If someone presses the cancel button on the Login page,
+ the Action class will return "cancel", this result will be selected,
+ and the framework will issue a redirect to the Welcome action.
+
+
+
+ The third result has no name,
+ so it will be called if the default success token is returned.
+ So, if the Login succeeds,
+ control will transfer to the MainMenu action.
+
+
+
+ The MailReader DAO exposes a "ExpiredPasswordException".
+ If the DAO throws this exception when the User logs in,
+ the framework will process the exception-mapping
+ and transfer control to the "ChangePassword" action.
+
+
+
+ Just in case any other Exceptions are thrown,
+ the MailReader application also defines a global handler.
+
+
+
+mailreader-default.xml exception-mapping
+<global-exception-mappings>
+ <exception-mapping
+ result="error"
+ exception="java.lang.Exception"/>
+</global-exception-mappings>
+
+
+
+ If an unexpected Exception is thrown,
+ the exception-mapping will transfer control to the action's "error" result,
+ or to a global "error" result.
+ The MailReader defines a global "error" result
+ which transfers control to an "Error.jsp" page
+ that can display the error message.
+
+
+
+Error.jsp
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title>Unexpected Error</title>
+ </head>
+ <body>
+ <h2>An unexpected error has occured</h2>
+ <p>
+ Please report this error to your system administrator
+ or appropriate technical support personnel.
+ Thank you for your cooperation.
+ </p>
+ <hr />
+ <h3>Error Message</h3>
+ <s:actionerror />
+ <p>
+ <s:property value="%{exception.message}"/>
+ </p>
+ <hr />
+ <h3>Technical Details</h3>
+ <p>
+ <s:property value="%{exceptionStack}"/>
+ </p>
+ <jsp:include page="Footer.jsp"/>
+ </body>
+</html>
+
+
+
+ The Error page uses property tags to expose
+ the Exception message and the Exception stack.
+
+
+
+ Finally, the Login action specifies an InterceptorStack
+ named defaultStack.
+ If you've worked with Struts 2 or WebWork 2 before, that might seem strange,
+ since "defaultStack" is the factory default.
+
+
+
+ In the MailReader application, most of the actions are only available
+ to authenticated users.
+ The exceptions are the Welcome, Login, and Register actions
+ which are available to everyone.
+ To authenticate clients,
+ the MailReader uses a custom Interceptor and a custom Interceptor stack.
+
+
+
+mailreader2.AuthenticationInterceptor
+package mailreader2;
+import com.opensymphony.xwork2.interceptor.Interceptor;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.Action;
+import java.util.Map;
+import org.apache.struts.apps.mailreader.dao.User;
+
+public class AuthenticationInterceptor implements Interceptor {
+ public void destroy () {}
+ public void init() {}
+ public String intercept (ActionInvocation actionInvocation) throws Exception {
+ Map session = actionInvocation.getInvocationContext().getSession();
+ User user = (User) session.get(Constants.USER_KEY);
+ boolean isAuthenticated = (null!=user) && (null!=user.getDatabase());
+ if (isAuthenticated ) {
+ return actionInvocation.invoke();
+ }
+ else {
+ return Action.LOGIN;
+ }
+ }
+}
+
+
+
+ The AuthenticationInterceptor looks to see if a User object
+ has been stored in the client's session state.
+ If so, it returns normally, and the next Interceptor in the set would be invoked.
+ If the User object is missing, the Interceptors returns "login".
+ The framework would match "login" to the global result,
+ and transfer control to the Login action.
+
+
+
+ The MailReader defines three custom Interceptor stacks: "user", "user-submit",
+ and "guest".
+
+
+
+mailreader-default.xml interceptors
+<interceptors>
+ <interceptor name="authentication "
+ class="mailreader2.AuthenticationInterceptor"/>
+ <interceptor-stack name="user " >
+ <interceptor-ref name="authentication" />
+ <interceptor-ref name="defaultStack"/>
+ </interceptor-stack>
+ <interceptor-stack name="user-submit " >
+ <interceptor-ref name="token-session" />
+ <interceptor-ref name="user"/>
+ </interceptor-stack>
+ <interceptor-stack name="guest " >
+ <interceptor-ref name="defaultStack"/>
+ </interceptor-stack>
+</interceptors>
+<default-interceptor-ref name="user"/>
+
+
+
+ The user stacks require that the client be authenticated.
+ In other words, that a User object is present in the session.
+ The actions using a guest stack can be accessed by any client.
+ The -submit versions of each can be used with actions
+ with forms, to guard against double submits.
+
+
+Double Submits
+
+
+ A common problem with designing web applications is that users are impatient
+ and response times can vary.
+ Sometimes, people will press a submit button a second time.
+ When this happens, the browser submits the request again,
+ so that we now have two requests for the same thing.
+ In the case of registering a user, if someone does press the submit button
+ again, and their timing is bad,
+ it could result in the system reporting that the username has already been
+ used.
+ (The first time the button was pressed.)
+ In practice, this would probably never happen, but for a longer running
+ process, like checking out a shopping cart,
+ it's easier for a double submit to occur.
+
+
+
+ To forestall double submits, and "back button" resubmits,
+ the framework can generate a token that is embedded in the form
+ and also kept in the session.
+ If the value of the tokens do not compare,
+ then we know that there has been a problem,
+ and that a form has been submitted twice or out of sequence.
+
+
+
+ The Token Session Interceptor will also attempt to provide intelligent
+ fail-over in the event of multiple requests using the same session.
+ That is, it will block subsequent requests until the first request is complete,
+ and then instead of returning the "invalid.token" code,
+ it will attempt to display the same response that the
+ original, valid action invocation would have displayed
+
+
+
+ Because the default interceptor stack will now authenticate the client,
+ we need to specify the standard "defaultStack" for the three
+ "guest actions", Welcome, Login, and Register.
+ Requiring authentification by default is the better practice, since it
+ means that we won't forget to enable it when creating new actions.
+ Meanwhile, those pesky users will ensure that we don't forget to disable
+ authentification for "guest" services.
+
+
+
+
+
+ On a successful login, the Main Menu page displays.
+ If you logged in using the demo account,
+ the page title should be "Main Menu Options for John Q. User".
+ Below this legend should be two links:
+
+
+
+
+ Edit your user registration profile
+
+
+ Log off MailReader Demonstration Application
+
+
+
+
+ Let's review the source for the "MainMenu" action mapping,
+ and the "MainMenu.jsp".
+
+
+
+Action mapping element for MainMenu
+<action name="MainMenu" class="mailreader2.MailreaderSupport">
+ <result>/pages/MainMenu.jsp</result>
+ </action>
+
+MainMenu.jsp
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <title><s:text name="mainMenu.title"/></title>
+ <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
+ type="text/css"/>
+ </head>
+
+ <body>
+ <h3><s:text name="mainMenu.heading"/> <s:property
+ value="user.fullName"/> </h3>
+ <ul>
+ <li><a href="<s:url action="Registration!input" />">
+ <s:text name="mainMenu.registration"/>
+ </a>
+ </li>
+ <li><a href="<s:url action="Logout" />">
+ <s:text name="mainMenu.logout"/>
+ </a>
+ </ul>
+ </body>
+</html>
+
+
+
+ The source for "MainMenu.jsp" also contains a new tag,
+ property , which we use to customize the page with the
+ "fullName" property of the authenticated user.
+
+
+
+ Displaying the user's full name is the reason the MainMenu action
+ references the MailreaderSupport class.
+ The MailreaderSupport class has a User property that the text tag
+ can access.
+ If we did not utilize MailreaderSupport,
+ the property tag would not be able to find the User object to print
+ the full name.
+
+
+
+ The customized MainMenu page offers two standard links.
+ One is to "Edit your user registration profile".
+ The other is to "Logout the MailReader Demonstration Application".
+
+
+
+
+
+ If you follow the "Edit your user registration profile" link from the Main
+ Menu page,
+ we will finally reach the heart of the MailReader application: the
+ Registration, or "Profile", page.
+ This page displays everything MailReader knows about you
+ (or at least your login),
+ while utilizing several interesting techniques.
+
+
+
+ To do double duty as the "Create" Registration page and the "Edit"
+ Registration page,
+ the "Registration.jsp" makes extensive use of the test tags,
+ to make it appears as though there are two distinct pages.
+
+
+
+Registration.jsp - head element
+<head>
+ <s:if test="task=='Create' ">
+ <title><s:text name="registration.title.create"/></title>
+ </s:if>
+ <s:if test="task=='Edit' ">
+ <title><s:text name="registration.title.edit"/></title>
+ </s:if>
+ <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
+ type="text/css"/>
+</head>
+
+
+
+ For example, if client is editing the form (task == 'Edit'),
+ the page inserts the username from the User object.
+ For a new Registration (task == 'Create'),
+ the page creates an empty data-entry field.
+
+
+
+Note:
+
+
+ Presention Logic -
+ The "test" tag is a convenient way to express presentation
+ logic within your pages.
+ Customized pages help to prevent user error,
+ and dynamic customization reduces the number of server pages your
+ application needs to maintain, among other benefits.
+
+
+
+
+
+ The page also uses logic tags to display a list of subscriptions
+ for the given user.
+ If the RegistrationForm has task set to "Edit",
+ the lower part of the page that lists the subscriptions is exposed.
+
+
+
+
+<s:if test="task == 'Edit'" >
+ <div align="center">
+ <h3><s:text name="heading.subscriptions"/></h3>
+ </div>
+ <!-- ... -->
+ </s:if>
+<jsp:include page="Footer.jsp"/>
+</body></html>
+
+
+
+ Otherwise, the page contains just the top portion --
+ a data-entry form for managing the user's registration.
+
+
+
+
+
+ Besides "if" there are several other control tags that you can use
+ to sort, filter, or iterate over data.
+ The Registration page includes a good example of using the iterator
+ tag to display the User's Subscriptions.
+
+
+
+ The subscriptions are stored in a hashtable object, which is in turn
+ stored in the user object.
+ So to display each subscription, we have to reach into the user object,
+ and loop through the members of the subscription collection.
+ Using the iterator tag, you can code it the way it sounds.
+
+
+
+Using iterator to list the Subscriptions
+<s:iterator value="user.subscriptions ">
+ <tr>
+ <td align="left">
+ <s:property value="host "/>
+ </td>
+ <td align="left">
+ <s:property value="username "/>
+ </td>
+ <td align="center">
+ <s:property value="type "/>
+ </td>
+ <td align="center">
+ <s:property value="autoConnect "/>
+ </td>
+ <td align="center">
+ <a href="<s:url action="Subscription!delete "><s:param name="host " value="host"/></s:url>">
+ <s:text name="registration.deleteSubscription"/>
+ </a>
+ <a href="<s:url action="Subscription!edit "><s:param name="host " value="host"/></s:url>">
+ <s:text name="registration.editSubscription"/>
+ </a>
+ </td>
+ </tr>
+</s:iterator>
+
+
+
+ When the iterator renders, it generates a list of Subscriptions for the current User.
+
+
+
+
+
+
Current Subscriptions
+
+
+
+
+
+ Host Name
+
+
+ User Name
+
+
+
+ Server Type
+
+
+ Auto
+
+
+ Action
+
+
+
+
+ mail.hotmail.com
+
+
+ user1234
+
+
+ pop3
+
+
+
+ false
+
+
+
+ Delete
+
+
+
+ Edit
+
+
+
+
+
+ mail.yahoo.com
+
+
+ jquser
+
+
+ imap
+
+
+ false
+
+
+
+ Delete
+
+
+
+ Edit
+
+
+
+
+ Add
+
+
+
+
+ Now look back at the code used to generate this block.
+
+
+ Notice anything nifty?
+
+
+ How about that the markup between the iterator tag is
+ actually simpler than the markup that we would use to render one row of the
+ table?
+
+
+ Instead of using a qualified reference like "value=user.subscription[0].host",
+ we use the simplest possible reference: "value=host".
+ We didn't have to define a local variable, and reference that local in the loop code.
+ The reference to each item in the list is automatically resolved, no fuss, no muss.
+
+
+ Nice trick!
+
+
+
+ The secret to this magic is the value stack .
+ Next to Interceptors, the value stack is probably the coolest thing there is about the
+ framework.
+ To explain the value stack, let's step back and start from the beginning.
+
+
+
+ Merging dynamic data into static web pages is a primary reason
+ we create web applications.
+ The Java API has a mechanism that allows you to
+ place objects in a servlet scope (page, request, session, or
+ application), and then retrieve them using a JSP scriplet.
+ If the object is placed directly in one of the scopes,
+ a JSP tag or scriptlet can find that object by searching page scope and
+ then request scope, and session scope, and finally application scope.
+
+
+
+ The value stack works much the same way, only better.
+ When you push an object on the value stack,
+ the public properties of that object become first-class properties of the stack.
+ The object's properties become the stack's properties.
+ If another object on the stack has properties of the same name,
+ the last object pushed onto the stack wins. (Last-In, First-Out.)
+
+
+
+ When the iterator tag loops through a collection,
+ it pushes each item in the collection onto the stack.
+ The item's properties become the stack's property.
+ In the case of the Subscriptions,
+ if the Subscription has a public Host property,
+ then during that iteration,
+ the stack can access the same property.
+
+
+
+ Of course, at the end of each iteration, the tag "pops" the item off the stack.
+ If we were to try and access the Host property later in the page,
+ it won't be there.
+
+
+
+ When an Action is invoked, the Action class is pushed onto the value stack.
+ Since the Action is on the value stack,
+ our tags can access any property of the Action
+ as if it were an implicit property of the page.
+ The tags don't access the Action directly.
+ If a textfield tag is told to render the "Username" property,
+ the tag asks the value stack for the value of "Username",
+ and the value stack returns the first property it finds by that name,
+ on any object on the stack.
+
+
+
+ The Validators also use the stack.
+ When validation fails on a field,
+ the value for the field is pushed onto the value stack.
+ As a result, if the client enters text into an Integer field,
+ the framework can still redisplay whatever was entered.
+ An invalid input value is not stored in the field (even if it could be).
+ The invalid input is pushed onto the stack for the scope of the request.
+
+
+
+ The Subscription list uses another new tag: the param tag.
+ As tags go, "param" takes very few parameters of its own: just "name" and "value",
+ and neither is required.
+ Although simple, "param" is one of the most powerful tags the framework provides.
+ Not so much because of what it does,
+ but because of what "param" allows the other tags to do.
+
+
+
+ Essentially, the "param" tag provides parameters to other tags.
+ A tag like "text" might be retrieving a message template with several replaceable
+ parameters.
+ No matter how many parameters are in the template, and no matter what they are named,
+ you can use the "param" tag to pass in whatever you need.
+
+
+pager.legend = Displaying {current} of {count} items matching {criteria}.
+...
+<s:text name="pager.legend">
+ <s:param name="current" value="42" />
+ <s:param name="count" value="314" />
+ <s:param name="criteria" value="Life, the Universe, and Everything" />
+</s:text>
+
+
+ In the case of an "url" tag,
+ we can use "param" to create the query string.
+ A statement like this:
+
+
+
+ <s:url action="Subscription!edit"><s:param name="host" value="host "/></s:url>">
+
+
+
+ can render a hyperlink like this:
+
+
+
+ <a href="/struts2-mailreader/Subscription!edit.do?host=mail.yahoo.com ">Edit</a>
+
+
+
+
+
+ If a hyperlink needs more parameters,
+ you can use "param" to add as many parameters as needed.
+
+
+
+
+
+ If we follow one of the "Edit" subscription links on the Registration page,
+ we come to the Subscriptions page,
+ which displays the details of our description in a data-entry form.
+ Let's have a look at the Subscription configuration
+ and follow the bouncing ball from page to action to page.
+
+
+
+mailreader-support.xml Subscription element
+<action name="Subscription!*" method="{1}" class="mailreader2.Subscription">
+ <result name="input">/pages/Subscription.jsp</result>
+ <result type="redirect-action">Registration!input</result>
+</action>
+
+
+
+ The Edit link specified the Subscription action,
+ but also includes the qualifier !edit .
+ The wildcard notation tells the framework to use any characters given after "Subscription!"
+ as the name of a method to invoke on the Action class,
+ instead of the default execute method.
+ The "alternate" execute methods are called alias methods.
+
+
+
+Subscription edit alias
+public String edit() {
+ setTask(Constants.EDIT); >
+ return find();
+}
+
+public String find() {
+ org.apache.struts.apps.mailreader.dao.Subscription
+ sub = findSubscription();
+ if (sub == null) {
+ return ERROR;
+ }
+ setSubscription(sub);
+ return INPUT;
+}
+
+
+
+ The "edit" alias has two responsibilities.
+ First, it must set the Task property to "Edit".
+ The Subscription page will render itself differently
+ depending on the value of the Task property.
+ Second, "edit" must locate the relevant Subscription
+ and set it to the Subscription property.
+ If all goes well, "edit" returns the INPUT token,
+ so that the "input" result will be invoked.
+
+
+
+ In the normal course, the Subscription should always be found,
+ since we selected the entry from a system-generated list.
+ If the Subscription is not found,
+ it would be because the database disappeared
+ or the request is being spoofed.
+ If the Subscription is not found,
+ edit returns the token for the global "error" result,
+ because this condition is unexpected.
+
+
+
+ The business logic for the "edit" alias is a simple wrapper
+ around the MailReader DAO classes.
+
+
+
+MailreaderSupport findSubscription()
+public Subscription findSubscription() {
+ return findSubscription(getHost());
+}
+
+public Subscription findSubscription(String host) {
+ Subscription subscription;
+ subscription = getUser().findSubscription(host);
+ return subscription;
+}
+
+
+
+ This code is very simple
+ and doesn't seem to provide much in the way of error handling.
+ But, that's OK.
+ Since the page is suppose to be entered from a link that we created,
+ we do expect everything to go right here.
+ But, if it doesn't, the global exception handler we defined in the
+ MailReader configuration will trap the exception for us.
+
+
+
+ Likewise, the AuthentificationInterceptor will ensure that only clients
+ with a valid User object can try to edit a Subscription.
+ If the session expired, or someone bookmarked the page,
+ the client will be redirected to the Login page automatically.
+
+
+
+ As a final layer of defense, we also configured a validator for Subscription,
+ to ensure that we are passed a Host parameter.
+
+
+
+Subscription-validation.xml
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <field name="host ">
+ <field-validator type="requiredstring ">
+ <message key="error.host.required"/>
+ </field-validator>
+ </field>
+</validators>
+
+
+
+ By keeping routine safety precautions out of the Action class,
+ the all-important Actions becomes smaller and easier to maintain.
+
+
+
+ After setting the relevent Subscription object to the Subscription property,
+ the framework transfers control to the (you guessed it) Subscription page.
+
+
+
+Subscription.jsp
+<%@ page contentType="text/html; charset=UTF-8" %>
+<%@ taglib prefix="s" uri="http://struts.apache.org/tags" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <s:if test="task=='Create'">
+ <title><s:text name="subscription.title.create"/></title>
+ </s:if>
+ <s:if test="task=='Edit'">
+ <title><s:text name="subscription.title.edit"/></title>
+ </s:if>
+ <s:if test="task=='Delete'">
+ <title><s:text name="subscription.title.delete"/></title>
+ </s:if>
+ <link href="<s:url value="/css/mailreader.css"/>" rel="stylesheet"
+ type="text/css"/>
+ </head>
+ <body onLoad="self.focus();document.Subscription.username.focus()">
+
+ <s:actionerror/>
+ <s:form action="Subscription!save" validate="true">
+ <s:token />
+ <s:hidden name="task"/>
+ <s:label label="%{getText('username')}" name="user.username"/>
+
+ <s:if test="task == 'Create'">
+ <s:textfield label="%{getText('mailHostname')}" name="host"/>
+ </s:if>
+ <s:else>
+ <s:label label="%{getText('mailHostname')}" name="host"/>
+ <s:hidden name="host"/>
+ </s:else>
+
+ <s:if test="task == 'Delete'">
+ <s:label label="%{getText('mailUsername')}"
+ name="subscription.username"/>
+ <s:label label="%{getText('mailPassword')}"
+ name="subscription.password"/>
+ <s:label label="%{getText('mailServerType')}"
+ name="subscription.type"/>
+ <s:label label="%{getText('autoConnect')}"
+ name="subscription.autoConnect"/>
+ <s:submit value="%{getText('button.confirm')}"/>
+ </s:if>
+ <s:else>
+ <s:textfield label="%{getText('mailUsername')}"
+ name="subscription.username"/>
+ <s:textfield label="%{getText('mailPassword')}"
+ name="subscription.password"/>
+ <s:select label="%{getText('mailServerType')}"
+ name="subscription.type" list="types"/>
+ <s:checkbox label="%{getText('autoConnect')}"
+ name="subscription.autoConnect"/>
+ <s:submit value="%{getText('button.save')}"/>
+ <s:reset value="%{getText('button.reset')}"/>
+ </s:else>
+
+ <s:submit action="Registration!input"
+ value="%{getText('button.cancel')}"
+ onclick="form.onsubmit=null"/>
+ </s:form>
+
+ <jsp:include page="Footer.jsp"/>
+ </body>
+</html>
+
+
+
+ As before, we'll discuss the tags and attributes that are new to this page:
+ "token", "hidden", "label", "select", and "checkbox".
+
+
+
+ The token tag works with the Token Session Interceptor to foil double
+ submits.
+ The tag generates a key that is embedded in the form and cached in the session.
+ Without this tag, the Interceptor can't work it's magic.
+
+
+
+ The hidden tag embeds the Task property into the form.
+ When the form is submitted,
+ the Subscription!save action will use the Task property to decide
+ whether to insert or update the form.
+
+
+
+ The label renders a "read only" version of a property,
+ suitable for placement in the form.
+ In Edit or Delete mode, we want the Host property to be immutable,
+ since it is used as a key. (As unwise as that might sound.)
+ In Delete mode, all of the properties are immutable,
+ since we are simply confirming the delete operation.
+
+
+
+ Saving the best for last, the Subscription form utilizes two more interesting
+ tags, "select" and "checkbox".
+
+
+
+ Unsurprisingly, the select tag renders a select control,
+ but the tag does so without requiring a lot of markup or redtape.
+
+
+<s:select label="%{getText('mailServerType')}"
+ name="subscription.type" list="types" />
+
+
+
+ The interesting attribute of the "select" tag is "list",
+ which, in our case, specifies a value of "types".
+ If we take another look at the Subscription action,
+ we can see that it implements an interface named Preparable
+ and populates a Types property in a method named "prepare".
+
+
+
+Subscription-validation.xml
+public class Subscription extends MailreaderSupport
+ implements Preparable {
+
+ private Map types = null;
+ public Map getTypes() {
+ return types;
+ }
+
+ public void prepare() {
+ Map m = new LinkedHashMap();
+ m.put("imap", "IMAP Protocol");
+ m.put("pop3", "POP3 Protocol");
+ types = m;
+ setHost(getSubscriptionHost());
+ }
+
+ // ...
+
+
+
+ The default Interceptor stack includes the PrepareInterceptor ,
+ which observes the Preparable interface.
+
+
+
+PrepareInterceptor
+public class PrepareInterceptor extends AroundInterceptor {
+
+ protected void after(ActionInvocation dispatcher, String result) throws Exception {
+ }
+
+ protected void before(ActionInvocation invocation) throws Exception {
+ Object action = invocation.getAction();
+ if (action instanceof Preparable) {
+ ((Preparable) action).prepare();
+ }
+ }
+}
+
+
+ The PrepareInterceptor ensures that the "prepare" method will always be called
+ before "execute" or an alias method is invoked.
+ We use "prepare" to setup the list of items for the select list to display.
+ We also transfer the Host property from our Subscription object
+ to a local property, where it is easier to manage.
+
+
+
+
+
+ Like many applications, the MailReader uses mainly String properties.
+ One exception is the AutoConnect property of the Subscription object.
+ On the HTML form, the AutoConnect property is represented by a checkbox.
+
+
+
+ When writing web applications, the checkbox can be a tricky control.
+ The Subscription object has a boolean AutoConnect property,
+ and the checkbox simply has to represent its state.
+ The problem is, if you clear a checkbox, the browser client will not submit anything .
+ Nada. Zip.
+ It is as if the checkbox control never existed.
+ The HTTP protocol has no way to affirm "false".
+ If the control is missing, we need to figure out it's been unclicked.
+
+
+
+ In Struts 1,
+ we use the reset method to work around checkbox issues.
+ In Struts 2, checkbox state is handled automatically.
+ The framework can detect when a checkbox tag has not been sent back,
+ and when that happens,
+ a default "false" value is used for the checkbox value.
+ No worries, mate.
+
+
+
+ If we press the SAVE button,
+ the form will be submitted to the Subscription!save action.
+ Since the save method needs some additional validation,
+ we can add a validation file.
+
+
+
+Subscription-Subscription!save-validation.xml
+<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+ <field name="host ">
+ <field-validator type="requiredstring ">
+ <message key="error.host.required"/>
+ </field-validator>
+ </field>
+</validators>
+
+
+
+ The validators follow the same type of inheritance path as the classes.
+ SubscriptionSave extends Subscription,
+ so when Subscription!save is validated,
+ the Host property specified by "Subscription-validation.xml" will also be required.
+
+
+
+ If validation succeeds, the save method of Subscription will fire.
+
+
+
+Subscription
+
+public String save () throws Exception {
+
+ if (Constants.DELETE.equals(getTask())) {
+ removeSubscription ();
+ }
+
+ if (Constants.CREATE.equals(getTask())) {
+ copySubscription( getHost());
+ }
+
+ saveUser();
+ return SUCCESS;
+}
+
+
+
+ The save method uses the Task property to handle
+ the special cases of deleting and creating,
+ and then updates the state of the User object.
+
+
+
+ The removeSubscription method calls the DAO facade,
+ and then updates the application state.
+
+
+
+removeSubscription
+public void removeSubscription () throws Exception {
+ getUser().removeSubscription(getSubscription());
+ getSession().remove(Constants.SUBSCRIPTION_KEY);
+}
+
+
+
+ The copySubscription method is a bit more interesting.
+ The MailReader DAO layer API includes some immutable fields
+ that can't be set once the object is created.
+ Because key fields are immutable,
+ we can't just create a Subscription, let the framework populate all the fields,
+ and then save it when we are done -- because some fields can't be populated,
+ except at construction.
+
+
+
+ One workaround would be to declare properties on the Action
+ for all the properties we need to pass to the Subscription or User objects.
+ When we are ready to create the object,
+ we could pass the new object values from the Action properties.
+
+
+
+ Another workaround is to declare only the immutable properties on the Action,
+ and then use what we can from the domain object.
+
+
+
+ This implementation of the MailReader utilizes the second alternative.
+ We define User and Subscription objects on our base Action,
+ and add other properties only as needed.
+
+
+
+ To add a new Subscription or User,
+ we create a blank object to capture whatever fields we can.
+ When this "input" object returns, we create a new object,
+ setting the immutable fields to appropriate values,
+ and copy over the rest of the properties.
+
+
+
+copySubscription
+public void copySubscription (String host) {
+ Subscription input = getSubscription();
+ Subscription sub = createSubscription(host);
+ if (null != sub) {
+ BeanUtils.setValues (sub, input, null);
+ setSubscription(sub);
+ setHost(sub.getHost());
+ }
+}
+
+
+
+ Of course, this is not a preferred solution,
+ but merely a way to work around an issue in the MailReader DAO API
+ that would not be easy for us change.
+
+
+Subscription Submit
+
+
+ When we pressed the SAVE button, there was one step that we overlooked.
+ The Mailreader application uses a "double submit" guard to keep people
+ from clicking the SAVE button multiple times and submitting the form again.
+
+
+
+ To add the double-submit guard, we can change the actions default processing
+ stack to user-submit.
+ But, we don't want to just copy and paste the other action settings from
+ the main Subscription action.
+ What we can do is put the subscription actions in their own package,
+ so that they can share result types.
+
+
+
+mailreader-support.xml
+
+</package>
+
+<package name="subscription" namespace="/" extends="mailreader-support">
+
+ <global-results>
+ <result name="input">/Subscription.jsp</result>
+ <result type="redirect-action">Registration!input</result>
+ </global-results>
+
+ <action name="Subscription!save" method="save" class="mailreader2.Subscription">
+ <interceptor-ref name="user-submit" />
+ </action>
+
+ <action name="Subscription!*" method="{1}" class="mailreader2.Subscription" />
+
+</package>
+
+<package name="wildcard" namespace="/" extends="mailreader-support">
+
+ <action name="*" class="mailreader2.MailreaderSupport">
+ <result>/{1}.jsp</result>
+ </action>
+
+</package>
+}
+
+
+
+ Aftering a successful save,
+ the Subscription Action will return "success",
+ and the framework will redirect us back to Registration input.
+
+
+Summary
+
+ At this point, we've booted the application, logged on,
+ reviewed a Registration record, and edited a Subscription.
+ Of course, there's more, but from here on, it is mostly more of the same.
+ The full source code for MailReader is
+
+ available online
+ and in the distribution.
+
+
+
+ Enjoy!
+
+
+
+
diff --git a/trunk/apps/pom.xml b/trunk/apps/pom.xml
new file mode 100644
index 000000000..eb115cc72
--- /dev/null
+++ b/trunk/apps/pom.xml
@@ -0,0 +1,216 @@
+
+
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-parent
+ 2.0.1
+
+ org.apache.struts
+ struts2-apps
+ pom
+ Webapps
+
+ blank
+ mailreader
+ portlet
+ showcase
+
+
+
+
+ apache-site
+ scp://people.apache.org/www/struts.apache.org/struts2/apps
+
+
+
+
+
+ hostedqa
+
+
+ com.hostedqa
+ hostedqa-remote-ant
+ 1.0-SNAPSHOT
+ test
+
+
+
+
+ codehaus
+ codehaus
+ http://repository.codehaus.org
+
+
+ maven-hostedqa
+ maven-hostedqa
+
+ true
+ always
+ ignore
+
+
+ true
+
+ http://maven.hostedqa.com
+
+
+
+
+
+
+ src/main/java
+
+ **/*.properties
+ **/*.xml
+
+
+
+
+
+ maven-antrun-plugin
+ org.apache.maven.plugins
+
+
+ package
+
+ run
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.hostedqa
+ hostedqa-remote-ant
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+
+
+
+
+
+ org.codehaus.cargo
+ cargo-maven2-plugin
+
+
+ tomcat5x
+ ${cargo.tomcat5x.home}
+ ${project.build.directory}/tomcat5x.log
+ ${project.build.directory}/tomcat5x.out
+
+
+ ${project.build.directory}/tomcat5x
+
+
+
+
+
+ maven-antrun-plugin
+
+
+ copy-sources
+ process-sources
+
+
+
+
+
+
+
+
+
+
+
+ run
+
+
+
+
+
+
+ ${pom.artifactId}
+
+
+
+
+
+
+ org.apache.struts
+ struts2-core
+ ${pom.version}
+
+
+
+
+ org.springframework
+ spring-beans
+ 1.2.8
+
+
+
+ org.springframework
+ spring-core
+ 1.2.8
+
+
+
+ org.springframework
+ spring-context
+ 1.2.8
+
+
+
+ org.springframework
+ spring-web
+ 1.2.8
+
+
+
+ org.springframework
+ spring-mock
+ 1.2.8
+ test
+
+
+
+
diff --git a/trunk/apps/portlet/README.txt b/trunk/apps/portlet/README.txt
new file mode 100644
index 000000000..efcb67bbc
--- /dev/null
+++ b/trunk/apps/portlet/README.txt
@@ -0,0 +1,17 @@
+README.txt - portlet
+
+This is a simple example of using the portlet API with Struts applications.
+
+For more on getting started with Struts, see
+
+* http://cwiki.apache.org/WW/home.html
+
+WARNING - Additional configuration required for deployment
+
+Due to difference in portlet contrainer implementations, the porlet
+WAR is not ready-to-run. Extract the porlet WAR, and then copy the
+contents of apps/portlet/src/main/etc// into the
+WAR's WEB-INF directory.
+
+
+----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/trunk/apps/portlet/pom.xml b/trunk/apps/portlet/pom.xml
new file mode 100644
index 000000000..64a1f11d0
--- /dev/null
+++ b/trunk/apps/portlet/pom.xml
@@ -0,0 +1,44 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-apps
+ 2.0.1
+
+ org.apache.struts
+ struts2-portlet
+ war
+ Portlet Webapp
+
+
+ portlet-api
+ portlet-api
+ 1.0
+ provided
+
+
+
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+ commons-lang
+ commons-lang
+ 2.0
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/exo/web.xml b/trunk/apps/portlet/src/main/etc/exo/web.xml
new file mode 100644
index 000000000..675c913d0
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/exo/web.xml
@@ -0,0 +1,63 @@
+
+
+
+ struts-portlet
+
+
+ contextConfigLocation
+ /WEB-INF/applicationContext*.xml
+
+
+ action2
+
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+
+ action2
+ /*
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ org.apache.struts2.portlet.context.ServletContextHolderListener
+
+
+
+
+ org.exoplatform.services.portletcontainer.impl.servlet.PortletApplicationListener
+
+
+
+
+ preparator
+
+ org.apache.struts2.portlet.context.PreparatorServlet
+
+
+
+ dwr
+ uk.ltd.getahead.dwr.DWRServlet
+
+
+ PortletWrapper
+
+ org.exoplatform.services.portletcontainer.impl.servlet.ServletWrapper
+
+
+
+
+ dwr
+ /dwr/*
+
+
+ PortletWrapper
+ /PortletWrapper
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/gridsphere/README-gridsphere.txt b/trunk/apps/portlet/src/main/etc/gridsphere/README-gridsphere.txt
new file mode 100644
index 000000000..e502e0699
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/gridsphere/README-gridsphere.txt
@@ -0,0 +1,2 @@
+Put the empty 'struts-portlet' file in the $CATALINA_HOME/webapps/gridsphere/WEB-INF/CustomPortal/portlets
+folder of your Gridsphere installation. You will need to add the gridsphere-ui-tags-2.1.2.jar to your project.
diff --git a/trunk/apps/portlet/src/main/etc/gridsphere/gridsphere-portlet.xml b/trunk/apps/portlet/src/main/etc/gridsphere/gridsphere-portlet.xml
new file mode 100644
index 000000000..ed15d11cb
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/gridsphere/gridsphere-portlet.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ JSR Portlet Servlet
+ PortletServlet
+
+
+
+
+ Portlet Servlet
+ en
+
+ Portlet Servlet
+ Portlet Servlet
+ A JSR Portlet Loader
+ portlet servlet
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/gridsphere/group.xml b/trunk/apps/portlet/src/main/etc/gridsphere/group.xml
new file mode 100644
index 000000000..d04e4e7b1
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/gridsphere/group.xml
@@ -0,0 +1,10 @@
+
+
+ StrutsPortlet
+ StrutsPortlet Example Application
+ PUBLIC
+
+ struts-portlet#StrutsPortlet
+ USER
+
+
diff --git a/trunk/apps/portlet/src/main/etc/gridsphere/layout.xml b/trunk/apps/portlet/src/main/etc/gridsphere/layout.xml
new file mode 100644
index 000000000..14a160bd9
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/gridsphere/layout.xml
@@ -0,0 +1,19 @@
+
+
+ StrutsPortlet Example
+
+
+ StrutsPortlet Example Application
+
+
+
+
+ struts-portlet#StrutsPortlet
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/gridsphere/struts-portlet b/trunk/apps/portlet/src/main/etc/gridsphere/struts-portlet
new file mode 100644
index 000000000..e69de29bb
diff --git a/trunk/apps/portlet/src/main/etc/gridsphere/web.xml b/trunk/apps/portlet/src/main/etc/gridsphere/web.xml
new file mode 100644
index 000000000..e453c960b
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/gridsphere/web.xml
@@ -0,0 +1,63 @@
+
+
+
+ struts-portlet
+
+
+ contextConfigLocation
+ /WEB-INF/applicationContext*.xml
+
+
+ action2
+
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+
+ action2
+ /*
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ org.apache.struts2.portlet.context.ServletContextHolderListener
+
+
+
+
+ org.gridlab.gridsphere.provider.portlet.jsr.PortletServlet
+
+
+
+
+ preparator
+
+ org.apache.struts2.portlet.context.PreparatorServlet
+
+
+
+ dwr
+ uk.ltd.getahead.dwr.DWRServlet
+
+
+ PortletServlet
+
+ org.gridlab.gridsphere.provider.portlet.jsr.PortletServlet
+
+
+
+
+ dwr
+ /dwr/*
+
+
+ PortletServlet
+ /jsr/struts-portlet
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-app.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-app.xml
new file mode 100644
index 000000000..02e09d53b
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-app.xml
@@ -0,0 +1,3 @@
+
+ struts-portlet
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-portlet.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-portlet.xml
new file mode 100644
index 000000000..663eaf395
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-portlet.xml
@@ -0,0 +1,12 @@
+
+
+ StrutsPortlet
+
+
+
+
+ StrutsPortlet2
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-web.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-web.xml
new file mode 100644
index 000000000..9d9c645cc
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.0/jboss-web.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.0/portlet-instances.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.0/portlet-instances.xml
new file mode 100644
index 000000000..c22073d5c
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.0/portlet-instances.xml
@@ -0,0 +1,11 @@
+
+
+
+ StrutsPortletInstance
+ StrutsPortlet
+
+
+ StrutsPortlet2Instance
+ StrutsPortlet2
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.0/struts-portlet-pages.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.0/struts-portlet-pages.xml
new file mode 100644
index 000000000..255c4530d
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.0/struts-portlet-pages.xml
@@ -0,0 +1,18 @@
+
+ default
+
+ struts-portlet
+
+ StrutsPortletWindow
+ struts-portlet.StrutsPortlet.StrutsPortletInstance
+ left
+ 0
+
+
+ StrutsPortletWindow2
+ struts-portlet.StrutsPortlet2.StrutsPortlet2Instance
+ right
+ 0
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-app.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-app.xml
new file mode 100644
index 000000000..02e09d53b
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-app.xml
@@ -0,0 +1,3 @@
+
+ struts-portlet
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-portlet.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-portlet.xml
new file mode 100644
index 000000000..663eaf395
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-portlet.xml
@@ -0,0 +1,12 @@
+
+
+ StrutsPortlet
+
+
+
+
+ StrutsPortlet2
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-web.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-web.xml
new file mode 100644
index 000000000..9d9c645cc
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.2/jboss-web.xml
@@ -0,0 +1,3 @@
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jbossportal2.2/struts-portlet-object.xml b/trunk/apps/portlet/src/main/etc/jbossportal2.2/struts-portlet-object.xml
new file mode 100644
index 000000000..2e062ad2a
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jbossportal2.2/struts-portlet-object.xml
@@ -0,0 +1,25 @@
+
+
+
+ overwrite
+ default
+
+
+ StrutsPortlet Example
+
+
+ StrutsWindow
+ StrutsPortletInstance
+ center
+ 0
+
+
+
+
+ overwrite
+
+ StrutsPortletInstance
+ struts-portlet.StrutsPortlet
+
+
+
diff --git a/trunk/apps/portlet/src/main/etc/jetspeed2/README-jetspeed2.txt b/trunk/apps/portlet/src/main/etc/jetspeed2/README-jetspeed2.txt
new file mode 100644
index 000000000..acde566d3
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jetspeed2/README-jetspeed2.txt
@@ -0,0 +1 @@
+Copy the struts-portlet.psml file to the JETSPEED2_INSTALL_DIR/webapps/jetspeed/WEB-INF/pages directory.
diff --git a/trunk/apps/portlet/src/main/etc/jetspeed2/struts-portlet.psml b/trunk/apps/portlet/src/main/etc/jetspeed2/struts-portlet.psml
new file mode 100644
index 000000000..d6c795489
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/jetspeed2/struts-portlet.psml
@@ -0,0 +1,20 @@
+
+
+ Struts Portlet Example Application
+ Struts Portlet Example Application
+
+
+
+
+
+
+
+
+
+ public-view
+
+
\ No newline at end of file
diff --git a/trunk/apps/portlet/src/main/etc/liferay3.6.1/web.xml b/trunk/apps/portlet/src/main/etc/liferay3.6.1/web.xml
new file mode 100644
index 000000000..b5fedfbad
--- /dev/null
+++ b/trunk/apps/portlet/src/main/etc/liferay3.6.1/web.xml
@@ -0,0 +1,75 @@
+
+
+
+ struts-portlet
+
+ contextConfigLocation
+ /WEB-INF/applicationContext*.xml
+
+
+ company_id
+ struts.apache.org
+
+
+ action2
+
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+
+ action2
+ /*
+
+
+
+ com.liferay.portal.servlet.PortletContextListener
+
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ org.apache.struts2.portlet.context.ServletContextHolderListener
+
+
+
+
+
+ StrutsPortlet
+
+ com.liferay.portal.servlet.PortletServlet
+
+
+ portlet-class
+
+ org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher
+
+
+ 0
+
+
+
+ preparator
+
+ org.apache.struts2.portlet.context.PreparatorServlet
+
+
+
+ dwr
+ uk.ltd.getahead.dwr.DWRServlet
+
+
+
+ dwr
+ /dwr/*
+
+
+ StrutsPortlet
+ /StrutsPortlet/*
+
+
+
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/ExampleAction.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/ExampleAction.java
new file mode 100644
index 000000000..93bf68ca6
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/ExampleAction.java
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example;
+
+import java.util.Map;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionSupport;
+
+public class ExampleAction extends ActionSupport {
+
+ private String name = "PortletWork Example";
+
+ public String getName() {
+ return name;
+ }
+
+ public Map getRenderParameters() {
+ return ActionContext.getContext().getParameters();
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExample.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExample.java
new file mode 100644
index 000000000..694eb12c4
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExample.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class FormExample extends ActionSupport {
+
+ String firstName = null;
+ String lastName = null;
+ public String execute() throws Exception {
+ // TODO Auto-generated method stub
+ return super.execute();
+ }
+ public String getFirstName() {
+ return firstName;
+ }
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+ public String getLastName() {
+ return lastName;
+ }
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExampleWithValidation.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExampleWithValidation.java
new file mode 100644
index 000000000..ec14710f7
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormExampleWithValidation.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class FormExampleWithValidation extends ActionSupport {
+ private String firstName = null;
+ private String lastName = null;
+
+ public String input() {
+ return SUCCESS;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+ public String getLastName() {
+ return lastName;
+ }
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormResultAction.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormResultAction.java
new file mode 100644
index 000000000..4dc22714e
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormResultAction.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example;
+
+import java.util.Collection;
+import java.util.Map;
+
+import javax.portlet.RenderRequest;
+
+import org.apache.struts2.portlet.context.PortletActionContext;
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class FormResultAction extends ActionSupport {
+
+ private String result = null;
+
+ public String getResult() {
+ return result;
+ }
+ public void setResult(String result) {
+ this.result = result;
+ }
+
+ public Collection getRenderParams() {
+ RenderRequest req = PortletActionContext.getRenderRequest();
+ Map params = req.getParameterMap();
+ return params.entrySet();
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormTestAction.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormTestAction.java
new file mode 100644
index 000000000..b2dacde5a
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/FormTestAction.java
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class FormTestAction extends ActionSupport {
+
+ private String name = null;
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/SavePrefsAction.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/SavePrefsAction.java
new file mode 100644
index 000000000..f9a5efae6
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/SavePrefsAction.java
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.PortletPreferences;
+
+import org.apache.struts2.portlet.context.PortletActionContext;
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class SavePrefsAction extends ActionSupport {
+ private String preferenceOne = null;
+ private String preferenceTwo = null;
+ public String getPreferenceOne() {
+ return preferenceOne;
+ }
+ public void setPreferenceOne(String preferenceOne) {
+ this.preferenceOne = preferenceOne;
+ }
+ public String getPreferenceTwo() {
+ return preferenceTwo;
+ }
+ public void setPreferenceTwo(String preferenceTwo) {
+ this.preferenceTwo = preferenceTwo;
+ }
+
+ public String execute() throws Exception {
+ ActionRequest req = PortletActionContext.getActionRequest();
+ PortletPreferences prefs = req.getPreferences();
+ prefs.setValue("preferenceOne", preferenceOne);
+ prefs.setValue("preferenceTwo", preferenceTwo);
+ prefs.store();
+ return SUCCESS;
+ }
+
+ public String showForm() throws Exception {
+ PortletPreferences prefs = PortletActionContext.getRequest().getPreferences();
+ preferenceOne = prefs.getValue("preferenceOne", "not set");
+ preferenceTwo = prefs.getValue("preferenceTwo", "not set");
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/SpringAction.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/SpringAction.java
new file mode 100644
index 000000000..78704a268
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/SpringAction.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example.spring;
+
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class SpringAction extends ActionSupport {
+
+ private ThingManager thingManager = null;
+ private String thing = null;
+
+ public void setThingManager(ThingManager thingManager) {
+ this.thingManager = thingManager;
+ }
+
+ public List getThings() {
+ return thingManager.getThings();
+ }
+
+ public String getThing() {
+ return thing;
+ }
+
+ public void setThing(String thing) {
+ this.thing = thing;
+ }
+
+ public String execute() {
+ if(StringUtils.isNotEmpty(thing)) {
+ thingManager.addThing(thing);
+ }
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/ThingManager.java b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/ThingManager.java
new file mode 100644
index 000000000..cbbb3b9f0
--- /dev/null
+++ b/trunk/apps/portlet/src/main/java/org/apache/struts2/portlet/example/spring/ThingManager.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.portlet.example.spring;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ */
+public class ThingManager {
+ private List things = new ArrayList();
+
+ public void addThing(String thing) {
+ things.add(thing);
+ }
+
+ public List getThings() {
+ return things;
+ }
+}
diff --git a/trunk/apps/portlet/src/main/resources/commons-logging.properties b/trunk/apps/portlet/src/main/resources/commons-logging.properties
new file mode 100644
index 000000000..a9eceaf5f
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/commons-logging.properties
@@ -0,0 +1,2 @@
+org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.Log4jFactory
+org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JCategoryLog
diff --git a/trunk/apps/portlet/src/main/resources/log4j.xml b/trunk/apps/portlet/src/main/resources/log4j.xml
new file mode 100644
index 000000000..c6803daad
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/log4j.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/resources/org/apache/struts2/portlet/example/FormExample-processValidationExample-validation.xml b/trunk/apps/portlet/src/main/resources/org/apache/struts2/portlet/example/FormExample-processValidationExample-validation.xml
new file mode 100644
index 000000000..4effe04b1
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/org/apache/struts2/portlet/example/FormExample-processValidationExample-validation.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ You must enter a first name
+
+
+
+
+ You must enter a last name
+
+
+
diff --git a/trunk/apps/portlet/src/main/resources/struts.properties b/trunk/apps/portlet/src/main/resources/struts.properties
new file mode 100644
index 000000000..cb40069a7
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/struts.properties
@@ -0,0 +1 @@
+struts.objectFactory = spring
diff --git a/trunk/apps/portlet/src/main/resources/template/xhtml/components/checkbox.vm b/trunk/apps/portlet/src/main/resources/template/xhtml/components/checkbox.vm
new file mode 100644
index 000000000..6d952f938
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/template/xhtml/components/checkbox.vm
@@ -0,0 +1,12 @@
+
+
+ $!struts.htmlEncode($parameters.label)
+
diff --git a/trunk/apps/portlet/src/main/resources/template/xhtml/components/datefield.vm b/trunk/apps/portlet/src/main/resources/template/xhtml/components/datefield.vm
new file mode 100644
index 000000000..7b3f44bef
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/template/xhtml/components/datefield.vm
@@ -0,0 +1,8 @@
+#set ($name = $parameters.name)
+#set ($label = $parameters.label)
+#set ($size = $parameters.mysize)
+#set ($yearsize = $parameters.yearsize)
+$label:
+ /
+ /
+ (dd/mm/yyyy)
diff --git a/trunk/apps/portlet/src/main/resources/template/xhtml/components/mytextfield.vm b/trunk/apps/portlet/src/main/resources/template/xhtml/components/mytextfield.vm
new file mode 100644
index 000000000..21c75be32
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/template/xhtml/components/mytextfield.vm
@@ -0,0 +1,15 @@
+
+
+ $!struts.htmlEncode($parameters.label)
+
diff --git a/trunk/apps/portlet/src/main/resources/validators.xml b/trunk/apps/portlet/src/main/resources/validators.xml
new file mode 100644
index 000000000..4c06d8b10
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/validators.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/resources/xwork.xml b/trunk/apps/portlet/src/main/resources/xwork.xml
new file mode 100644
index 000000000..001f60a71
--- /dev/null
+++ b/trunk/apps/portlet/src/main/resources/xwork.xml
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+ /WEB-INF/view/index.jsp
+
+
+
+
+ /WEB-INF/view/formExampleInput.jsp
+
+
+
+
+
+ /WEB-INF/view/formExampleInput.jsp
+
+
+ /WEB-INF/view/formExample.jsp
+
+
+
+
+
+ /WEB-INF/view/formExampleInputValidation.jsp
+
+
+
+
+
+ /WEB-INF/view/formExample.jsp
+
+
+ /WEB-INF/view/formExampleInputValidation.jsp
+
+
+
+
+
+
+ /WEB-INF/view/tokenExampleInput.jsp
+
+
+
+
+
+ /WEB-INF/view/tokenExampleInput.jsp
+
+
+ /WEB-INF/view/tokenExampleInput.jsp
+
+
+ /WEB-INF/view/tokenExample.jsp
+
+
+
+
+
+
+
+ /WEB-INF/view/springExample.jsp
+
+
+
+
+
+ /WEB-INF/view/ajaxExample.jsp
+
+
+
+
+ /WEB-INF/view/ajaxData.jsp
+
+
+
+
+ /WEB-INF/view/freeMarkerExampleInput.ftl
+
+
+
+
+ /view/processFreeMarkerView.action?firstName=${firstName}&lastName=${lastName}
+
+
+
+ /WEB-INF/view/freeMarkerExample.ftl
+
+
+
+ /WEB-INF/view/helloWorld.vm
+
+
+
+
+
+
+ /WEB-INF/edit/index.jsp
+
+
+ /WEB-INF/edit/test.jsp
+
+
+
+ /WEB-INF/edit/formExampleInput.jsp
+
+
+
+
+
+ /WEB-INF/edtt/formExampleInput.jsp
+
+
+ /edit/processFormExampleForward.action?firstName=${firstName}&lastName=${lastName}
+
+
+
+
+
+ /WEB-INF/edit/formExample.jsp
+
+
+
+
+
+
+ /WEB-INF/edit/namespaceTest.jsp
+
+
+
+
+
+ /WEB-INF/help/index.jsp
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/applicationContext.xml b/trunk/apps/portlet/src/main/webapp/WEB-INF/applicationContext.xml
new file mode 100644
index 000000000..6bd3e54ba
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/applicationContext.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/dwr.xml b/trunk/apps/portlet/src/main/webapp/WEB-INF/dwr.xml
new file mode 100644
index 000000000..4ede30035
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/dwr.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ );
+ ]]>
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/defaultEdit.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/defaultEdit.jsp
new file mode 100644
index 000000000..61b05c612
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/defaultEdit.jsp
@@ -0,0 +1,5 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+StrutsPortlet
+This is the default edit page!
+
+ ">Set some prefs
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExample.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExample.jsp
new file mode 100644
index 000000000..7d62563ab
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExample.jsp
@@ -0,0 +1,5 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
Hello
+
+ ">Back to front page
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExampleInput.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExampleInput.jsp
new file mode 100644
index 000000000..43c981df6
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/formExampleInput.jsp
@@ -0,0 +1,8 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+Input your name
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/index.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/index.jsp
new file mode 100644
index 000000000..6b03c99f3
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/index.jsp
@@ -0,0 +1,11 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+There are no examples in edit mode yet
+
+
+ ">Test
+
+ ">Form test
+
+ ">Dummy test
+
+ ">Back to view mode
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/namespaceTest.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/namespaceTest.jsp
new file mode 100644
index 000000000..7e373a131
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/namespaceTest.jsp
@@ -0,0 +1,4 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+ ">Test page for namespace /edit/test
+
+ ">Back to edit index
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsForm.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsForm.jsp
new file mode 100644
index 000000000..af8b02cd7
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsForm.jsp
@@ -0,0 +1,6 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsSaved.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsSaved.jsp
new file mode 100644
index 000000000..6aca664f1
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/prefsSaved.jsp
@@ -0,0 +1,5 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+The preferences has been saved.
+
+ ">Back
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/test.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/test.jsp
new file mode 100644
index 000000000..615860c47
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/edit/test.jsp
@@ -0,0 +1,4 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+ ">Test page
+
+ ">Back to edit index
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/help/defaultHelp.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/help/defaultHelp.jsp
new file mode 100644
index 000000000..c8fb774f7
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/help/defaultHelp.jsp
@@ -0,0 +1 @@
+This is the default help page!
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/help/index.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/help/index.jsp
new file mode 100644
index 000000000..ea58ff820
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/help/index.jsp
@@ -0,0 +1 @@
+There are no examples in help mode yet
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/portlet.xml b/trunk/apps/portlet/src/main/webapp/WEB-INF/portlet.xml
new file mode 100644
index 000000000..1d1896695
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/portlet.xml
@@ -0,0 +1,118 @@
+
+
+ Struts Test Portlet
+ StrutsPortlet
+ Struts Test Portlet
+
+ org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher
+
+
+
+ viewNamespace
+ /view
+
+
+
+ defaultViewAction
+ index
+
+
+
+ editNamespace
+ /edit
+
+
+
+ defaultEditAction
+ index
+
+
+
+ helpNamespace
+ /help
+
+
+
+ defaultHelpAction
+ index
+
+
+
+
+ 0
+
+
+ text/html
+ edit
+ help
+
+
+ en
+
+
+ My StrutsPortlet portlet
+ SP
+ struts,portlet
+
+
+
+
+ Struts Test Portlet2
+ StrutsPortlet2
+ Struts Test Portlet2
+
+ org.apache.struts2.portlet.dispatcher.Jsr168Dispatcher
+
+
+
+ viewNamespace
+ /view
+
+
+
+ defaultViewAction
+ index
+
+
+
+ editNamespace
+ /edit
+
+
+
+ defaultEditAction
+ index
+
+
+
+ helpNamespace
+ /help
+
+
+
+ defaultHelpAction
+ index
+
+
+
+
+ 0
+
+
+ text/html
+ edit
+ help
+
+
+ en
+
+
+ My StrutsPortlet portlet2
+ SP2
+ struts,portlet
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/readme.txt b/trunk/apps/portlet/src/main/webapp/WEB-INF/readme.txt
new file mode 100644
index 000000000..53633149c
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/readme.txt
@@ -0,0 +1,10 @@
+Configurations:
+
+JBoss Portal specific configuration files
+-----------------------------------------
+jboss-app.xml
+jboss-portlet.xml
+jboss-web.xml
+portlet-instances.xml
+struts-example-object.xml
+struts-example-pages.xml
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajax.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajax.jsp
new file mode 100644
index 000000000..e24ec7c17
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajax.jsp
@@ -0,0 +1 @@
+Hello from Ajax!
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxData.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxData.jsp
new file mode 100644
index 000000000..796b0d77d
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxData.jsp
@@ -0,0 +1 @@
+This data is fetched via Ajax! The server time is <%= new java.util.Date() %>
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxExample.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxExample.jsp
new file mode 100644
index 000000000..d0b55af40
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/ajaxExample.jsp
@@ -0,0 +1,48 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+ ">
+This is a tabbed pane with two panels that fetches data from a remote action via ajax
+
+
+
+ This is the left pane
+
+
+
+
+
+
+
+ middle tab
+
+
+
+
+
+
+
+
+
+A DIV that waits for 5 seconds before loading the contents
+
+ Waiting for data
+
+A DIV that is updated every 2 seconds
+Initial Content
+
+
+ ">Back to front page
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExample.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExample.jsp
new file mode 100644
index 000000000..7d62563ab
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExample.jsp
@@ -0,0 +1,5 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+Hello
+
+ ">Back to front page
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInput.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInput.jsp
new file mode 100644
index 000000000..468d0eb4f
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInput.jsp
@@ -0,0 +1,8 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+Input your name
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInputValidation.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInputValidation.jsp
new file mode 100644
index 000000000..f64745747
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/formExampleInputValidation.jsp
@@ -0,0 +1,8 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+ ">
+Input your name
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExample.ftl b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExample.ftl
new file mode 100644
index 000000000..cb70dc7c4
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExample.ftl
@@ -0,0 +1,3 @@
+Hello from FreeMarker, ${firstName} ${lastName}!
+
+ ">Back to front page
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExampleInput.ftl b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExampleInput.ftl
new file mode 100644
index 000000000..86ebbfbe7
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/freeMarkerExampleInput.ftl
@@ -0,0 +1,5 @@
+<@s.form action="processFreeMarkerExample" method="POST">
+ <@s.textfield label="First name" name="firstName"/>
+ <@s.textfield label="Last name" name="lastName"/>
+ <@s.submit value="Say hello!"/>
+@s.form>
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/helloWorld.vm b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/helloWorld.vm
new file mode 100644
index 000000000..b2933c41b
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/helloWorld.vm
@@ -0,0 +1 @@
+Hello World from velocity!
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/index.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/index.jsp
new file mode 100644
index 000000000..5686c2e94
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/index.jsp
@@ -0,0 +1,15 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+Welcome to the Struts example portlet
+
+Here you'll find examples of what is possible with the Struts Portlet integration framework.
+
+ ">A simple form
+ ">Validation
+ ">Token
+ ">Spring integration
+ ">Ajax
+ ">FreeMarker
+ ">Velocity
+ ">Go to edit mode and see what's there
+ ">Go to help mode and see what's there
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/notImplemented.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/notImplemented.jsp
new file mode 100644
index 000000000..a3af7eb2b
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/notImplemented.jsp
@@ -0,0 +1 @@
+This example has not yet been implemented
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/springExample.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/springExample.jsp
new file mode 100644
index 000000000..8a0da4287
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/springExample.jsp
@@ -0,0 +1,16 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+Example of Spring managed singleton. All the 'things' are contained in a Spring defined ThingManager
+
+Things in the list:
+
+
+
+
+
+
+
+
+
+
+ ">Back to front page
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExample.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExample.jsp
new file mode 100644
index 000000000..e41c9e96e
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExample.jsp
@@ -0,0 +1,5 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+The form was successfully submitted with a valid token
+
+ "/>Back to front page
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExampleInput.jsp b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExampleInput.jsp
new file mode 100644
index 000000000..7aa2e31aa
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/view/tokenExampleInput.jsp
@@ -0,0 +1,20 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+ ERROR:
+
+
+
+
+
+
+Form with invalid token
+
+
+
+
+Form with valid token
+
+
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/WEB-INF/web.xml b/trunk/apps/portlet/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..62ba4e4c1
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ contextConfigLocation
+ /WEB-INF/applicationContext*.xml
+
+
+ action2
+
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+
+ action2
+ /*
+
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ org.apache.struts2.portlet.context.ServletContextHolderListener
+
+
+
+
+
+ preparator
+
+ org.apache.struts2.portlet.context.PreparatorServlet
+
+
+
+ dwr
+ uk.ltd.getahead.dwr.DWRServlet
+
+
+
+ dwr
+ /dwr/*
+
+
+
diff --git a/trunk/apps/portlet/src/main/webapp/styles/styles.css b/trunk/apps/portlet/src/main/webapp/styles/styles.css
new file mode 100644
index 000000000..3dafc085a
--- /dev/null
+++ b/trunk/apps/portlet/src/main/webapp/styles/styles.css
@@ -0,0 +1,7 @@
+.wwFormTable {}
+.label {font-style:italic; }
+.errorLabel {font-style:italic; color:red; }
+.errorMessage {font-weight:bold; text-align: center; color:red; }
+.checkboxLabel {}
+.checkboxErrorLabel {color:red; }
+.required {color:red;}
diff --git a/trunk/apps/showcase/README.txt b/trunk/apps/showcase/README.txt
new file mode 100644
index 000000000..4d483c78c
--- /dev/null
+++ b/trunk/apps/showcase/README.txt
@@ -0,0 +1,10 @@
+README.txt - showcase
+
+Showcase is a collection of examples with code that you might be adopt and
+adapt in your own applications.
+
+For more on getting started with Struts, see
+
+* http://cwiki.apache.org/WW/home.html
+
+----------------------------------------------------------------------------
\ No newline at end of file
diff --git a/trunk/apps/showcase/pom.xml b/trunk/apps/showcase/pom.xml
new file mode 100644
index 000000000..b01f55e39
--- /dev/null
+++ b/trunk/apps/showcase/pom.xml
@@ -0,0 +1,161 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-apps
+ 2.0.1
+
+ org.apache.struts
+ struts2-showcase
+ war
+ Showcase Webapp
+
+
+ hostedqa
+
+ 12
+ 9
+ 8
+ 7
+
+
+
+
+
+
+ org.apache.struts
+ struts2-struts1-plugin
+ ${pom.version}
+
+
+
+ org.apache.struts
+ struts2-jsf-plugin
+ ${pom.version}
+
+
+
+ org.apache.struts
+ struts2-config-browser-plugin
+ ${pom.version}
+
+
+
+ org.apache.struts
+ struts2-sitemesh-plugin
+ ${pom.version}
+
+
+
+ org.apache.struts
+ struts2-tiles-plugin
+ ${pom.version}
+
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+
+
+ velocity
+ velocity
+ 1.4
+ true
+
+
+
+ velocity-tools
+ velocity-tools
+ 1.1
+ true
+
+
+
+
+ opensymphony
+ sitemesh
+ 2.2.1
+
+
+ log4j
+ log4j
+ 1.2.9
+
+
+ uk.ltd.getahead
+ dwr
+ 1.1-beta-3
+
+
+ org.apache.myfaces.core
+ myfaces-impl
+ 1.1.2
+
+
+ org.apache.myfaces.core
+ myfaces-api
+ 1.1.2
+
+
+ org.rifers
+ rife-continuations
+ 0.0.2
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.1.1
+
+
+
+
+
+
+
+
+ org.mortbay.jetty
+ maven-jetty-plugin
+ 6.0.1
+
+ 10
+
+
+
+ org.apache.myfaces.core
+ myfaces-impl
+ 1.1.2
+
+
+ org.apache.myfaces.core
+ myfaces-api
+ 1.1.2
+
+
+ log4j
+ log4j
+ 1.2.9
+
+
+
+
+
+
+
+ src/main/resources
+
+
+ src/main/java
+
+ **/*.java
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/quickstart.xml b/trunk/apps/showcase/quickstart.xml
new file mode 100644
index 000000000..6bb5a9039
--- /dev/null
+++ b/trunk/apps/showcase/quickstart.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+ ../../../xwork/xwork.iml,../../core/struts2-core.iml,struts2-showcase.iml
+
+
+ /showcase
+
+
+ 8080
+
+
+
+
+
+
+
+ src/main/resources
+ target/classes
+ ../../core/target/classes
+
+
+
+
+
+ /
+ src/main/webapp
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.java
new file mode 100644
index 000000000..242c9d7bb
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.java
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+/**
+ * DateAction
+ *
+ */
+public class DateAction extends ActionSupport {
+
+ private static DateFormat DF = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
+
+ private Date now;
+ private Date past;
+ private Date future;
+ private Date after;
+ private Date before;
+
+
+ public String getDate() {
+ return DF.format(new Date());
+ }
+
+
+ /**
+ * @return Returns the future.
+ */
+ public Date getFuture() {
+ return future;
+ }
+
+ /**
+ * @return Returns the now.
+ */
+ public Date getNow() {
+ return now;
+ }
+
+ /**
+ * @return Returns the past.
+ */
+ public Date getPast() {
+ return past;
+ }
+
+ /**
+ *
+ * @return Returns the before date.
+ */
+ public Date getBefore() {
+ return before;
+ }
+
+ /**
+ *
+ * @return Returns the after date.
+ */
+ public Date getAfter() {
+ return after;
+ }
+
+ /**
+ * @see com.opensymphony.xwork2.ActionSupport#execute()
+ */
+ public String execute() throws Exception {
+ Calendar cal = GregorianCalendar.getInstance();
+ now = cal.getTime();
+ cal.roll(Calendar.DATE, -1);
+ cal.roll(Calendar.HOUR, -3);
+ past = cal.getTime();
+ cal.roll(Calendar.DATE, 2);
+ future = cal.getTime();
+
+ cal.roll(Calendar.YEAR, -1);
+ before = cal.getTime();
+
+ cal.roll(Calendar.YEAR, 2);
+ after = cal.getTime();
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.properties
new file mode 100644
index 000000000..d49c743a5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DateAction.properties
@@ -0,0 +1 @@
+struts.date.format=yyyy/MM/dd hh:mm:ss
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DynamicTreeSelectAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DynamicTreeSelectAction.java
new file mode 100644
index 000000000..3fd80af93
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/DynamicTreeSelectAction.java
@@ -0,0 +1,35 @@
+package org.apache.struts2.showcase;
+
+import org.apache.struts2.showcase.ajax.tree.Category;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+//START SNIPPET: treeExampleDynamicJavaSelected
+
+public class DynamicTreeSelectAction extends ActionSupport {
+
+ private long nodeId;
+ private Category currentCategory;
+
+
+ public void setNodeId(long nodeId) {
+ this.nodeId = nodeId;
+ }
+ public long getNodeId() {
+ return nodeId;
+ }
+
+
+ public String execute() throws Exception {
+ currentCategory = Category.getById(nodeId);
+ return SUCCESS;
+ }
+
+
+ public String getNodeName() {
+ return currentCategory.getName();
+ }
+}
+
+//START SNIPPET: treeExampleDynamicJavaSelected
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/Guess.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/Guess.java
new file mode 100644
index 000000000..b74d2f3d4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/Guess.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.Preparable;
+import com.uwyn.rife.continuations.ContinuableObject;
+
+import java.util.Random;
+
+// START SNIPPET: example
+public class Guess extends ActionSupport implements Preparable, ContinuableObject {
+ int guess;
+
+ public void prepare() throws Exception {
+ // We clear the error message state before the action.
+ // That is because with continuations, the original (or cloned) action is being
+ // executed, which will still have the old errors and potentially cause problems,
+ // such as with the workflow interceptor
+ clearErrorsAndMessages();
+ }
+
+ public String execute() throws Exception {
+ int answer = new Random().nextInt(100) + 1;
+ int tries = 5;
+
+ while (answer != guess && tries > 0) {
+ pause(Action.SUCCESS);
+
+ if (guess > answer) {
+ addFieldError("guess", "Too high!");
+ } else if (guess < answer) {
+ addFieldError("guess", "Too low!");
+ }
+
+ tries--;
+ }
+
+ if (answer == guess) {
+ addActionMessage("You got it!");
+ } else {
+ addActionMessage("You ran out of tries, the answer was " + answer);
+ }
+
+ return Action.SUCCESS;
+ }
+
+ public void setGuess(int guess) {
+ this.guess = guess;
+ }
+}
+// END SNIPPET: example
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfOptiontransferselectAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfOptiontransferselectAction.java
new file mode 100644
index 000000000..ddc236055
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfOptiontransferselectAction.java
@@ -0,0 +1,223 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class LotsOfOptiontransferselectAction extends ActionSupport {
+
+ private List _favouriteCartoonCharactersKeys;
+ private List _notFavouriteCartoonCharactersKeys;
+
+ private List _favouriteCarsKeys;
+ private List _notFavouriteCarsKeys;
+
+ private List _favouriteMotorcyclesKeys;
+ private List _notFavouriteMotorcyclesKeys;
+
+ private List _favouriteCountriesKeys;
+ private List _notFavouriteCountriesKeys;
+
+ private List _prioritisedFavouriteCartoonCharacters;
+ private List _prioritisedFavouriteCars;
+ private List _prioritisedFavouriteCountries;
+
+
+
+ // Cartoon Characters
+ public Map getDefaultFavouriteCartoonCharacters() {
+ Map m = new LinkedHashMap();
+ m.put("heMan", "He-Man");
+ m.put("popeye", "Popeye");
+ m.put("mockeyMouse", "Mickey Mouse");
+ return m;
+ }
+
+ public Map getDefaultNotFavouriteCartoonCharacters() {
+ Map m = new LinkedHashMap();
+ m.put("donaldDuck", "Donald Duck");
+ m.put("atomicAnt", "Atomic Ant");
+ m.put("pinkPainter", "Pink Painter");
+ return m;
+ }
+
+ public List getFavouriteCartoonCharacters() {
+ return _favouriteCartoonCharactersKeys;
+ }
+
+ public void setFavouriteCartoonCharacters(List favouriteCartoonCharacters) {
+ _favouriteCartoonCharactersKeys = favouriteCartoonCharacters;
+ }
+
+ public List getNotFavouriteCartoonCharacters() {
+ return _notFavouriteCartoonCharactersKeys;
+ }
+
+ public void setNotFavouriteCartoonCharacters(List notFavouriteCartoonCharacters) {
+ _notFavouriteCartoonCharactersKeys = notFavouriteCartoonCharacters;
+ }
+
+
+
+
+
+ // Cars
+ public Map getDefaultFavouriteCars() {
+ Map m = new LinkedHashMap();
+ m.put("alfaRomeo", "Alfa Romeo");
+ m.put("Toyota", "Toyota");
+ m.put("Mitsubitshi", "Mitsubitshi");
+ return m;
+ }
+
+ public Map getDefaultNotFavouriteCars() {
+ Map m = new LinkedHashMap();
+ m.put("ford", "Ford");
+ m.put("landRover", "Land Rover");
+ m.put("mercedes", "Mercedes");
+ return m;
+ }
+
+ public List getFavouriteCars() {
+ return _favouriteCarsKeys;
+ }
+
+ public void setFavouriteCars(List favouriteCars) {
+ _favouriteCarsKeys = favouriteCars;
+ }
+
+ public List getNotFavouriteCars() {
+ return _notFavouriteCarsKeys;
+ }
+
+ public void setNotFavouriteCars(List notFavouriteCars) {
+ _notFavouriteCarsKeys = notFavouriteCars;
+ }
+
+
+
+ // Motorcycles
+ public Map getDefaultFavouriteMotorcycles() {
+ Map m = new LinkedHashMap();
+ m.put("honda", "Honda");
+ m.put("yamaha", "Yamaha");
+ m.put("Aprillia", "Aprillia");
+ return m;
+ }
+
+ public Map getDefaultNotFavouriteMotorcycles() {
+ Map m = new LinkedHashMap();
+ m.put("cagiva", "Cagiva");
+ m.put("harleyDavidson", "Harley Davidson");
+ m.put("suzuki", "Suzuki");
+ return m;
+ }
+
+ public List getFavouriteMotorcycles() {
+ return _favouriteMotorcyclesKeys;
+ }
+
+ public void setFavouriteMotorcycles(List favouriteMotorcycles) {
+ _favouriteMotorcyclesKeys = favouriteMotorcycles;
+ }
+
+ public List getNotFavouriteMotorcycles() {
+ return _notFavouriteMotorcyclesKeys;
+ }
+
+ public void setNotFavouriteMotorcycles(List notFavouriteMotorcycles) {
+ _notFavouriteMotorcyclesKeys = notFavouriteMotorcycles;
+ }
+
+
+
+ // Countries
+ public Map getDefaultFavouriteCountries() {
+ Map m = new LinkedHashMap();
+ m.put("england", "England");
+ m.put("america", "America");
+ m.put("brazil", "Brazil");
+ return m;
+ }
+
+ public Map getDefaultNotFavouriteCountries() {
+ Map m = new LinkedHashMap();
+ m.put("germany", "Germany");
+ m.put("china", "China");
+ m.put("russia", "Russia");
+ return m;
+ }
+
+ public List getFavouriteCountries() {
+ return _favouriteCountriesKeys;
+ }
+
+ public void setFavouriteCountries(List favouriteCountries) {
+ _favouriteCountriesKeys = favouriteCountries;
+ }
+
+ public List getNotFavouriteCountries() {
+ return _notFavouriteCountriesKeys;
+ }
+
+ public void setNotFavouriteCountries(List notFavouriteCountries) {
+ _notFavouriteCountriesKeys = notFavouriteCountries;
+ }
+
+
+ public List getPrioritisedFavouriteCartoonCharacters() {
+ return _prioritisedFavouriteCartoonCharacters;
+ }
+ public void setPrioritisedFavouriteCartoonCharacters(List prioritisedFavouriteCartoonCharacters) {
+ _prioritisedFavouriteCartoonCharacters = prioritisedFavouriteCartoonCharacters;
+ }
+
+ public List getPrioritisedFavouriteCars() {
+ return _prioritisedFavouriteCars;
+ }
+ public void setPrioritisedFavouriteCars(List prioritisedFavouriteCars) {
+ _prioritisedFavouriteCars = prioritisedFavouriteCars;
+ }
+
+
+ public List getPrioritisedFavouriteCountries() {
+ return _prioritisedFavouriteCountries;
+ }
+ public void setPrioritisedFavouriteCountries(List prioritisedFavouriteCountries) {
+ _prioritisedFavouriteCountries = prioritisedFavouriteCountries;
+ }
+
+
+
+
+ // actions
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml
new file mode 100644
index 000000000..8bf17c7c1
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Description1 Is Required !!!
+
+
+
+
+
+ Description2 Is Required !!!
+
+
+
+
+
+ Description3 Is Required !!!
+
+
+
+
+
+ Description4 Is Required !!!
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction.java
new file mode 100644
index 000000000..952fda972
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/LotsOfRichtexteditorAction.java
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ */
+public class LotsOfRichtexteditorAction extends ActionSupport {
+
+ public String description1;
+ public String description2 = "This is Description 2";
+ public String description3;
+ public String description4 = "This is Description 4";
+
+ public String getDescription1() {
+ return this.description1;
+ }
+ public void setDescription1(String description1) {
+ this.description1 = description1;
+ }
+
+
+ public String getDescription2() {
+ return this.description2;
+ }
+ public void setDescription2(String description2) {
+ this.description2 = description2;
+ }
+
+
+ public String getDescription3() {
+ return this.description3;
+ }
+ public void setDescription3(String description3) {
+ this.description3 = description3;
+ }
+
+
+
+
+ public String getDescription4() {
+ return this.description4;
+ }
+ public void setDescription4(String description4) {
+ this.description4 = description4;
+ }
+
+
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ShowDynamicTreeAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ShowDynamicTreeAction.java
new file mode 100644
index 000000000..838d76b63
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ShowDynamicTreeAction.java
@@ -0,0 +1,17 @@
+package org.apache.struts2.showcase;
+
+import org.apache.struts2.showcase.ajax.tree.Category;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+// START SNIPPET: treeExampleDynamicJavaShow
+
+public class ShowDynamicTreeAction extends ActionSupport {
+
+ public Category getTreeRootNode() {
+ return Category.getById(1);
+ }
+}
+
+// END SNIPPET: treeExampleDynamicJavaShow
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample-conversion.properties
new file mode 100644
index 000000000..2415dcf3c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample-conversion.properties
@@ -0,0 +1 @@
+Element_friends = java.lang.String
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample.java
new file mode 100644
index 000000000..3a2729c83
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/UITagExample.java
@@ -0,0 +1,314 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase;
+
+import org.apache.struts2.ServletActionContext;
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.Validateable;
+import com.opensymphony.xwork2.util.ValueStack;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.File;
+
+/**
+ */
+public class UITagExample extends ActionSupport implements Validateable {
+
+ private static final long serialVersionUID = -94044809860988047L;
+
+
+ String name;
+ Date birthday;
+ String bio;
+ String favoriteColor;
+ List friends;
+ boolean legalAge;
+ String state;
+ String region;
+ File picture;
+ String pictureContentType;
+ String pictureFileName;
+ String favouriteLanguage;
+ String favouriteVehicalType = "MotorcycleKey";
+ String favouriteVehicalSpecific = "YamahaKey";
+
+ List leftSideCartoonCharacters;
+ List rightSideCartoonCharacters;
+
+ List favouriteLanguages = new ArrayList();
+ List vehicalTypeList = new ArrayList();
+ Map vehicalSpecificMap = new HashMap();
+
+ String thoughts;
+
+ public UITagExample() {
+ favouriteLanguages.add(new Language("EnglishKey", "English Language"));
+ favouriteLanguages.add(new Language("FrenchKey", "French Language"));
+ favouriteLanguages.add(new Language("SpanishKey", "Spanish Language"));
+
+ VehicalType car = new VehicalType("CarKey", "Car");
+ VehicalType motorcycle = new VehicalType("MotorcycleKey", "Motorcycle");
+ vehicalTypeList.add(car);
+ vehicalTypeList.add(motorcycle);
+
+ List cars = new ArrayList();
+ cars.add(new VehicalSpecific("MercedesKey", "Mercedes"));
+ cars.add(new VehicalSpecific("HondaKey", "Honda"));
+ cars.add(new VehicalSpecific("FordKey", "Ford"));
+
+ List motorcycles = new ArrayList();
+ motorcycles.add(new VehicalSpecific("SuzukiKey", "Suzuki"));
+ motorcycles.add(new VehicalSpecific("YamahaKey", "Yamaha"));
+
+ vehicalSpecificMap.put(car, cars);
+ vehicalSpecificMap.put(motorcycle, motorcycles);
+ }
+
+
+
+ public List getLeftSideCartoonCharacters() {
+ return leftSideCartoonCharacters;
+ }
+ public void setLeftSideCartoonCharacters(List leftSideCartoonCharacters) {
+ this.leftSideCartoonCharacters = leftSideCartoonCharacters;
+ }
+
+
+ public List getRightSideCartoonCharacters() {
+ return rightSideCartoonCharacters;
+ }
+ public void setRightSideCartoonCharacters(List rightSideCartoonCharacters) {
+ this.rightSideCartoonCharacters = rightSideCartoonCharacters;
+ }
+
+
+ public String getFavouriteVehicalType() {
+ return favouriteVehicalType;
+ }
+
+ public void setFavouriteVehicalType(String favouriteVehicalType) {
+ this.favouriteVehicalType = favouriteVehicalType;
+ }
+
+ public String getFavouriteVehicalSpecific() {
+ return favouriteVehicalSpecific;
+ }
+
+ public void setFavouriteVehicalSpecific(String favouriteVehicalSpecific) {
+ this.favouriteVehicalSpecific = favouriteVehicalSpecific;
+ }
+
+ public List getVehicalTypeList() {
+ return vehicalTypeList;
+ }
+
+ public List getVehicalSpecificList() {
+ ValueStack stack = ServletActionContext.getValueStack(ServletActionContext.getRequest());
+ Object vehicalType = stack.findValue("top");
+ if (vehicalType != null && vehicalType instanceof VehicalType) {
+ List l = (List) vehicalSpecificMap.get(vehicalType);
+ return l;
+ }
+ return Collections.EMPTY_LIST;
+ }
+
+ public List getFavouriteLanguages() {
+ return favouriteLanguages;
+ }
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Date getBirthday() {
+ return birthday;
+ }
+
+ public void setBirthday(Date birthday) {
+ this.birthday = birthday;
+ }
+
+ public String getBio() {
+ return bio;
+ }
+
+ public void setBio(String bio) {
+ this.bio = bio;
+ }
+
+ public String getFavoriteColor() {
+ return favoriteColor;
+ }
+
+ public void setFavoriteColor(String favoriteColor) {
+ this.favoriteColor = favoriteColor;
+ }
+
+ public List getFriends() {
+ return friends;
+ }
+
+ public void setFriends(List friends) {
+ this.friends = friends;
+ }
+
+ public boolean isLegalAge() {
+ return legalAge;
+ }
+
+ public void setLegalAge(boolean legalAge) {
+ this.legalAge = legalAge;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+
+ public String getRegion() {
+ return region;
+ }
+
+ public void setRegion(String region) {
+ this.region = region;
+ }
+
+ public void setPicture(File picture) {
+ this.picture = picture;
+ }
+
+ public void setPictureContentType(String pictureContentType) {
+ this.pictureContentType = pictureContentType;
+ }
+
+ public void setPictureFileName(String pictureFileName) {
+ this.pictureFileName = pictureFileName;
+ }
+
+ public void setFavouriteLanguage(String favouriteLanguage) {
+ this.favouriteLanguage = favouriteLanguage;
+ }
+
+ public String getFavouriteLanguage() {
+ return favouriteLanguage;
+ }
+
+
+ public void setThoughts(String thoughts) {
+ this.thoughts = thoughts;
+ }
+
+ public String getThoughts() {
+ return this.thoughts;
+ }
+
+
+
+ public String doSubmit() {
+ return SUCCESS;
+ }
+
+
+
+ // === inner class
+ public static class Language {
+ String description;
+ String key;
+
+ public Language(String key, String description) {
+ this.key = key;
+ this.description = description;
+ }
+
+ public String getKey() {
+ return key;
+ }
+ public String getDescription() {
+ return description;
+ }
+
+ }
+
+
+ public static class VehicalType {
+ String key;
+ String description;
+ public VehicalType(String key, String description) {
+ this.key = key;
+ this.description = description;
+ }
+
+ public String getKey() { return this.key; }
+ public String getDescription() { return this.description; }
+
+ public boolean equals(Object obj) {
+ if (! (obj instanceof VehicalType)) {
+ return false;
+ }
+ else {
+ return key.equals(((VehicalType)obj).getKey());
+ }
+ }
+
+ public int hashCode() {
+ return key.hashCode();
+ }
+ }
+
+
+ public static class VehicalSpecific {
+ String key;
+ String description;
+ public VehicalSpecific(String key, String description) {
+ this.key = key;
+ this.description = description;
+ }
+
+ public String getKey() { return this.key; }
+ public String getDescription() { return this.description; }
+
+ public boolean equals(Object obj) {
+ if (! (obj instanceof VehicalSpecific)) {
+ return false;
+ }
+ else {
+ return key.equals(((VehicalSpecific)obj).getKey());
+ }
+ }
+
+ public int hashCode() {
+ return key.hashCode();
+ }
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java
new file mode 100644
index 000000000..d57b30f54
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/AbstractCRUDAction.java
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.action;
+
+import org.apache.log4j.Logger;
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.showcase.dao.Dao;
+import org.apache.struts2.showcase.model.IdEntity;
+
+import java.util.Collection;
+import java.io.Serializable;
+
+/**
+ * AbstractCRUDAction.
+ *
+ */
+
+public abstract class AbstractCRUDAction extends ActionSupport {
+
+ private static final Logger log = Logger.getLogger(AbstractCRUDAction.class);
+
+ private Collection availableItems;
+ private String[] toDelete;
+
+ protected abstract Dao getDao();
+
+
+ public Collection getAvailableItems() {
+ return availableItems;
+ }
+
+ public String[] getToDelete() {
+ return toDelete;
+ }
+
+ public void setToDelete(String[] toDelete) {
+ this.toDelete = toDelete;
+ }
+
+ public String list() throws Exception {
+ this.availableItems = getDao().findAll();
+ if (log.isDebugEnabled()) {
+ log.debug("AbstractCRUDAction - [list]: " + (availableItems !=null?""+availableItems.size():"no") + " items found");
+ }
+ return execute();
+ }
+
+ public String delete() throws Exception {
+ if (toDelete != null) {
+ int count=0;
+ for (int i = 0, j=toDelete.length; i < j; i++) {
+ count = count + getDao().delete(toDelete[i]);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("AbstractCRUDAction - [delete]: " + count + " items deleted.");
+ }
+ }
+ return SUCCESS;
+ }
+
+ /**
+ * Utility method for fetching already persistent object from storage for usage in params-prepare-params cycle.
+ *
+ * @param tryId The id to try to get persistent object for
+ * @param tryObject The object, induced by first params invocation, possibly containing id to try to get persistent
+ * object for
+ * @return The persistent object, if found. null otherwise.
+ */
+ protected IdEntity fetch(Serializable tryId, IdEntity tryObject) {
+ IdEntity result = null;
+ if (tryId != null) {
+ result = getDao().get(tryId);
+ } else if (tryObject != null) {
+ result = getDao().get(tryObject.getId());
+ }
+ return result;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties
new file mode 100644
index 000000000..21d3eda97
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties
@@ -0,0 +1 @@
+Element_selectedSkills=java.lang.String
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-validation.xml
new file mode 100644
index 000000000..c49959888
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction-validation.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.java
new file mode 100644
index 000000000..b434d0333
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.java
@@ -0,0 +1,122 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.action;
+
+import com.opensymphony.xwork2.Preparable;
+import org.apache.log4j.Logger;
+import org.apache.struts2.showcase.application.TestDataProvider;
+import org.apache.struts2.showcase.dao.Dao;
+import org.apache.struts2.showcase.dao.EmployeeDao;
+import org.apache.struts2.showcase.model.Employee;
+import org.apache.struts2.showcase.model.Skill;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * JsfEmployeeAction.
+ */
+
+public class EmployeeAction extends AbstractCRUDAction implements Preparable {
+
+ private static final long serialVersionUID = 7047317819789938957L;
+
+ private static final Logger log = Logger.getLogger(EmployeeAction.class);
+
+ private Long empId;
+ protected EmployeeDao employeeDao;
+ private Employee currentEmployee;
+ private List selectedSkills;
+
+ public Long getEmpId() {
+ return empId;
+ }
+
+ public void setEmpId(Long empId) {
+ this.empId = empId;
+ }
+
+ public Employee getCurrentEmployee() {
+ return currentEmployee;
+ }
+
+ public void setCurrentEmployee(Employee currentEmployee) {
+ this.currentEmployee = currentEmployee;
+ }
+
+ public String[] getAvailablePositions() {
+ return TestDataProvider.POSITIONS;
+ }
+
+ public List getAvailableLevels() {
+ return Arrays.asList(TestDataProvider.LEVELS);
+ }
+
+ public List getSelectedSkills() {
+ return selectedSkills;
+ }
+
+ public void setSelectedSkills(List selectedSkills) {
+ this.selectedSkills = selectedSkills;
+ }
+
+ protected Dao getDao() {
+ return employeeDao;
+ }
+
+ public void setEmployeeDao(EmployeeDao employeeDao) {
+ if (log.isDebugEnabled()) {
+ log.debug("JsfEmployeeAction - [setEmployeeDao]: employeeDao injected.");
+ }
+ this.employeeDao = employeeDao;
+ }
+
+ /**
+ * This method is called to allow the action to prepare itself.
+ *
+ * @throws Exception thrown if a system level exception occurs.
+ */
+ public void prepare() throws Exception {
+ Employee preFetched = (Employee) fetch(getEmpId(), getCurrentEmployee());
+ if (preFetched != null) {
+ setCurrentEmployee(preFetched);
+ }
+ }
+
+ public String execute() throws Exception {
+ if (getCurrentEmployee() != null && getCurrentEmployee().getOtherSkills() != null) {
+ setSelectedSkills(new ArrayList());
+ Iterator it = getCurrentEmployee().getOtherSkills().iterator();
+ while (it.hasNext()) {
+ getSelectedSkills().add(((Skill) it.next()).getName());
+ }
+ }
+ return super.execute();
+ }
+
+ public String save() throws Exception {
+ if (getCurrentEmployee() != null) {
+ setEmpId((Long) employeeDao.merge(getCurrentEmployee()));
+ employeeDao.setSkills(getEmpId(), getSelectedSkills());
+ }
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.properties
new file mode 100644
index 000000000..e2e548b3c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction.properties
@@ -0,0 +1,9 @@
+employee=Employee
+employee.firstName=First Name
+employee.lastName=Last Name
+employee.description=Description
+
+employee.id.required=Id is required
+employee.lastName.required=Last Name is required
+employee.birthDate.required=Birthdate is required
+employee.backtolist=Back to Employee List
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction_de.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction_de.properties
new file mode 100644
index 000000000..ca594de4d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/EmployeeAction_de.properties
@@ -0,0 +1,9 @@
+employee=Mitarbeiter
+employee.firstName=Vorname
+employee.lastName=Nachname
+employee.description=Beschreibung
+
+employee.id.required=ID muß angegeben werden
+employee.lastName.required=Nachname wird benötigt
+employee.birthDate.required=Geburtsdatum wird benötigt
+employee.backtolist=Zurück zur Mitarbeiterliste
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction-validation.xml
new file mode 100644
index 000000000..486e79f61
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction-validation.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ true
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.java
new file mode 100644
index 000000000..dfcb5dfa0
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.java
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.action;
+
+import org.apache.struts2.showcase.dao.Dao;
+import org.apache.struts2.showcase.dao.SkillDao;
+import org.apache.struts2.showcase.model.Skill;
+import com.opensymphony.xwork2.Preparable;
+import org.apache.log4j.Logger;
+
+/**
+ * SkillAction.
+ *
+ */
+
+public class SkillAction extends AbstractCRUDAction implements Preparable {
+
+ private static final Logger log = Logger.getLogger(SkillAction.class);
+
+ private String skillName;
+ protected SkillDao skillDao;
+ private Skill currentSkill;
+
+ public String getSkillName() {
+ return skillName;
+ }
+
+ public void setSkillName(String skillName) {
+ this.skillName = skillName;
+ }
+
+ protected Dao getDao() {
+ return skillDao;
+ }
+
+ public void setSkillDao(SkillDao skillDao) {
+ if (log.isDebugEnabled()) {
+ log.debug("SkillAction - [setSkillDao]: skillDao injected.");
+ }
+ this.skillDao = skillDao;
+ }
+
+ public Skill getCurrentSkill() {
+ return currentSkill;
+ }
+
+ public void setCurrentSkill(Skill currentSkill) {
+ this.currentSkill = currentSkill;
+ }
+
+ /**
+ * This method is called to allow the action to prepare itself.
+ *
+ * @throws Exception thrown if a system level exception occurs.
+ */
+ public void prepare() throws Exception {
+ Skill preFetched = (Skill) fetch(getSkillName(), getCurrentSkill());
+ if (preFetched != null) {
+ setCurrentSkill(preFetched);
+ }
+ }
+
+ public String save() throws Exception {
+ if (getCurrentSkill() != null) {
+ setSkillName((String) skillDao.merge(getCurrentSkill()));
+ }
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.properties
new file mode 100644
index 000000000..27b7c81df
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction.properties
@@ -0,0 +1,6 @@
+skill=Skill
+skill.name=Name
+skill.description=Description
+
+skill.name.required=Name is required
+skill.backtolist=Back to Skill List
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction_de.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction_de.properties
new file mode 100644
index 000000000..7c7156f71
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/action/SkillAction_de.properties
@@ -0,0 +1,6 @@
+skill=Kenntnis
+skill.name=Name
+skill.description=Beschreibung
+
+skill.name.required=Name muss angegeben werden
+skill.backtolist=Zurück zur Kenntnis Liste
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain1.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain1.java
new file mode 100644
index 000000000..c9dfed9e9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain1.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.actionchaining;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ */
+public class ActionChain1 extends ActionSupport {
+
+ private static final long serialVersionUID = -6811701750042275153L;
+
+ private String actionChain1Property1 = "Property Set In Action Chain 1";
+
+ public String getActionChain1Property1() {
+ return actionChain1Property1;
+ }
+ public void setActionChain1Property1(String actionChain1Property1) {
+ this.actionChain1Property1 = actionChain1Property1;
+ }
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain2.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain2.java
new file mode 100644
index 000000000..e4b30f9a8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain2.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.actionchaining;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ */
+public class ActionChain2 extends ActionSupport {
+
+ private static final long serialVersionUID = 3951745956044674809L;
+
+ private String actionChain1Property1;
+ private String actionChain2Property1 = "Property Set in Action Chain 2";
+
+
+ public String getActionChain1Property1() {
+ return actionChain1Property1;
+ }
+ public void setActionChain1Property1(String actionChain1Property1) {
+ this.actionChain1Property1 = actionChain1Property1;
+ }
+
+
+
+ public String getActionChain2Property1() {
+ return actionChain2Property1;
+ }
+ public void setActionChain2Property1(String actionChain2Property1) {
+ this.actionChain2Property1 = actionChain2Property1;
+ }
+
+
+
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain3.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain3.java
new file mode 100644
index 000000000..53e7587a5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/actionchaining/ActionChain3.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.actionchaining;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ */
+public class ActionChain3 extends ActionSupport {
+
+ private static final long serialVersionUID = -1456568865075250621L;
+
+ private String actionChain1Property1;
+ private String actionChain2Property1;
+ private String actionChain3Property1 = "Property set in Action Chain 3";
+
+
+ public String getActionChain1Property1() {
+ return actionChain1Property1;
+ }
+ public void setActionChain1Property1(String actionChain1Property1) {
+ this.actionChain1Property1 = actionChain1Property1;
+ }
+
+
+
+ public String getActionChain2Property1() {
+ return actionChain2Property1;
+ }
+ public void setActionChain2Property1(String actionChain2Property1) {
+ this.actionChain2Property1 = actionChain2Property1;
+ }
+
+
+
+ public String getActionChain3Property1() {
+ return actionChain3Property1;
+ }
+ public void setActionChain3Property1(String actionChain3Property1) {
+ this.actionChain3Property1 = actionChain3Property1;
+ }
+
+
+
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/AjaxTestAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/AjaxTestAction.java
new file mode 100644
index 000000000..89e7efccb
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/AjaxTestAction.java
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.ajax;
+
+import com.opensymphony.xwork2.Action;
+
+
+/**
+ */
+public class AjaxTestAction implements Action {
+
+ private static int counter = 0;
+ private String data;
+
+ public long getServerTime() {
+ return System.currentTimeMillis();
+ }
+
+ public int getCount() {
+ return ++counter;
+ }
+
+ public String getData() {
+ return data;
+ }
+
+ public void setData(String data) {
+ this.data = data;
+ }
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example4ShowPanelAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example4ShowPanelAction.java
new file mode 100644
index 000000000..8935bead7
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example4ShowPanelAction.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.ajax;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * @version $Date$ $Id$
+ */
+public class Example4ShowPanelAction extends ActionSupport {
+
+ private String name;
+ private String gender;
+
+ private static final long serialVersionUID = 7751976335066456596L;
+
+ public String panel1() throws Exception {
+ return SUCCESS;
+ }
+
+ public String panel2() throws Exception {
+ return SUCCESS;
+ }
+
+ public String panel3() throws Exception {
+ return SUCCESS;
+ }
+
+ public String getGender() {
+ return gender;
+ }
+
+ public void setGender(String gender) {
+ this.gender = gender;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getTodayDate() {
+ SimpleDateFormat sdf = new SimpleDateFormat("dd-MMMM-yyyy");
+ return sdf.format(new Date());
+ }
+
+ public String getTodayTime() {
+ SimpleDateFormat sdf = new SimpleDateFormat("kk:mm:ss");
+ return sdf.format(new Date());
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example5Action.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example5Action.java
new file mode 100644
index 000000000..da3c4708b
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/Example5Action.java
@@ -0,0 +1,23 @@
+package org.apache.struts2.showcase.ajax;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class Example5Action extends ActionSupport {
+
+ private static final long serialVersionUID = 2111967621952300611L;
+
+ private String name;
+ private Integer age;
+
+
+ public String getName() { return name; }
+ public void setName(String name) { this.name = name; }
+
+ public Integer getAge() { return age; }
+ public void setAge(Integer age) { this.age = age; }
+
+ @Override
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Category.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Category.java
new file mode 100644
index 000000000..a66cadb15
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Category.java
@@ -0,0 +1,101 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.ajax.tree;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ */
+public class Category {
+ private static Map catMap = new HashMap();
+
+ static {
+ new Category(1, "Root",
+ new Category(2, "Java",
+ new Category(3, "Web Frameworks",
+ new Category(4, "Struts"),
+ new Category(7, "Stripes"),
+ new Category(8, "Rife")),
+ new Category(9, "Persistence",
+ new Category(10, "iBatis"),
+ new Category(11, "Hibernate"),
+ new Category(12, "JDO"),
+ new Category(13, "JDBC"))),
+ new Category(14, "JavaScript",
+ new Category(15, "Dojo"),
+ new Category(16, "Prototype"),
+ new Category(17, "Scriptaculous"),
+ new Category(18, "OpenRico"),
+ new Category(19, "DWR")));
+ }
+
+ public static Category getById(long id) {
+ return catMap.get(id);
+ }
+
+ private long id;
+ private String name;
+ private List children;
+ private boolean toggle;
+
+ public Category(long id, String name, Category... children) {
+ this.id = id;
+ this.name = name;
+ this.children = new ArrayList();
+ for (Category child : children) {
+ this.children.add(child);
+ }
+
+ catMap.put(id, this);
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List getChildren() {
+ return children;
+ }
+
+ public void setChildren(List children) {
+ this.children = children;
+ }
+
+ public void toggle() {
+ toggle = !toggle;
+ }
+
+ public boolean isToggle() {
+ return toggle;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/GetCategory.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/GetCategory.java
new file mode 100644
index 000000000..329c653c0
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/GetCategory.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.ajax.tree;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class GetCategory extends ActionSupport {
+ private long catId;
+ private Category category;
+
+ public String execute() throws Exception {
+ if (catId < 1) {
+ // force the root
+ catId = 1;
+ }
+
+ category = Category.getById(catId);
+
+ return SUCCESS;
+ }
+
+ public void setCatId(long catId) {
+ this.catId = catId;
+ }
+
+ public Category getCategory() {
+ return category;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Toggle.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Toggle.java
new file mode 100644
index 000000000..80a50a292
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/ajax/tree/Toggle.java
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.ajax.tree;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class Toggle extends GetCategory {
+ public String execute() throws Exception {
+ super.execute();
+
+ getCategory().toggle();
+
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/MemoryStorage.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/MemoryStorage.java
new file mode 100644
index 000000000..2c09afc15
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/MemoryStorage.java
@@ -0,0 +1,140 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.application;
+
+import org.apache.struts2.showcase.exception.CreateException;
+import org.apache.struts2.showcase.exception.DuplicateKeyException;
+import org.apache.struts2.showcase.exception.StorageException;
+import org.apache.struts2.showcase.exception.UpdateException;
+import org.apache.struts2.showcase.model.IdEntity;
+import org.apache.struts2.showcase.application.Storage;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * MemoryStorage.
+ * Very simple in-memory persistence emulation.
+ *
+ */
+
+public class MemoryStorage implements Storage {
+
+ private static final long serialVersionUID = 8611213748834904125L;
+
+
+ private Map memory = new HashMap();
+
+ private Map getEntityMap ( Class entityClass ) {
+ if (entityClass != null) {
+ Map tryMap = (Map) memory.get(entityClass);
+ if (tryMap == null) {
+ synchronized(memory) {
+ tryMap = new HashMap();
+ memory.put(entityClass, tryMap);
+ }
+ }
+ return tryMap;
+ } else {
+ return null;
+ }
+ }
+
+ private IdEntity intStore( Class entityClass, IdEntity object ) {
+ getEntityMap(entityClass).put(object.getId(), object);
+ return object;
+ }
+
+ public IdEntity get( Class entityClass, Serializable id ) {
+ if (entityClass != null && id != null) {
+ return (IdEntity) getEntityMap(entityClass).get(id);
+ } else {
+ return null;
+ }
+ }
+
+ public Serializable create ( IdEntity object ) throws CreateException {
+ if (object == null) {
+ throw new CreateException("Either given class or object was null");
+ }
+ if (object.getId() == null) {
+ throw new CreateException("Cannot store object with null id");
+ }
+ if (get(object.getClass(), object.getId()) != null) {
+ throw new DuplicateKeyException("Object with this id already exists.");
+ }
+ return intStore(object.getClass(), object).getId();
+ }
+
+ public IdEntity update ( IdEntity object ) throws UpdateException {
+ if (object == null) {
+ throw new UpdateException("Cannot update null object.");
+ }
+ if ( get(object.getClass(), object.getId())==null ) {
+ throw new UpdateException("Object to update not found.");
+ }
+ return intStore(object.getClass(), object);
+ }
+
+ public Serializable merge ( IdEntity object ) throws StorageException {
+ if (object == null) {
+ throw new StorageException("Cannot merge null object");
+ }
+ if (object.getId() == null || get(object.getClass(), object.getId())==null) {
+ return create(object);
+ } else {
+ return update(object).getId();
+ }
+ }
+
+ public int delete( Class entityClass, Serializable id ) throws CreateException {
+ try {
+ if (get(entityClass, id) != null) {
+ getEntityMap(entityClass).remove(id);
+ return 1;
+ } else {
+ return 0;
+ }
+ } catch (Exception e) {
+ throw new CreateException(e);
+ }
+ }
+
+ public int delete( IdEntity object ) throws CreateException {
+ if (object == null) {
+ throw new CreateException("Cannot delete null object");
+ }
+ return delete(object.getClass(), object.getId());
+ }
+
+ public Collection findAll( Class entityClass ) {
+ if (entityClass != null) {
+ return getEntityMap(entityClass).values();
+ } else {
+ return new ArrayList();
+ }
+ }
+
+ public void reset() {
+ this.memory = new HashMap();
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/Storage.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/Storage.java
new file mode 100644
index 000000000..ceba1832f
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/Storage.java
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.application;
+
+import org.apache.struts2.showcase.model.IdEntity;
+import org.apache.struts2.showcase.exception.CreateException;
+import org.apache.struts2.showcase.exception.UpdateException;
+import org.apache.struts2.showcase.exception.StorageException;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * Storage. Interface.
+ *
+ */
+
+public interface Storage extends Serializable {
+ IdEntity get( Class entityClass, Serializable id );
+
+ Serializable create ( IdEntity object ) throws CreateException;
+
+ IdEntity update ( IdEntity object ) throws UpdateException;
+
+ Serializable merge ( IdEntity object ) throws StorageException;
+
+ int delete( Class entityClass, Serializable id ) throws CreateException;
+
+ int delete( IdEntity object ) throws CreateException;
+
+ Collection findAll( Class entityClass );
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java
new file mode 100644
index 000000000..6378a00e3
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/application/TestDataProvider.java
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.application;
+
+import org.apache.struts2.showcase.dao.EmployeeDao;
+import org.apache.struts2.showcase.dao.SkillDao;
+import org.apache.struts2.showcase.exception.StorageException;
+import org.apache.struts2.showcase.model.Employee;
+import org.apache.struts2.showcase.model.Skill;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.InitializingBean;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.Arrays;
+
+/**
+ * TestDataProvider.
+ *
+ */
+
+public class TestDataProvider implements Serializable, InitializingBean {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Logger log = Logger.getLogger(TestDataProvider.class);
+
+ public static final String[] POSITIONS = {
+ "Developer",
+ "System Architect",
+ "Sales Manager",
+ "CEO"
+ };
+
+ public static final String[] LEVELS = {
+ "Junior",
+ "Senior",
+ "Master"
+ };
+
+ private static final Skill[] TEST_SKILLS = {
+ new Skill("WW-SEN", "Struts Senior Developer"),
+ new Skill("WW-JUN", "Struts Junior Developer"),
+ new Skill("SPRING-DEV", "Spring Developer")
+ };
+
+ public static final Employee[] TEST_EMPLOYEES = {
+ new Employee(new Long(1), "Alan", "Smithee", new Date(), new Float(2000f), true, POSITIONS[0],
+ TEST_SKILLS[0], null, "alan", LEVELS[0], "Nice guy"),
+ new Employee(new Long(2), "Robert", "Robson", new Date(), new Float(10000f), false, POSITIONS[1],
+ TEST_SKILLS[1], Arrays.asList(TEST_SKILLS).subList(1,TEST_SKILLS.length), "rob", LEVELS[1], "Smart guy")
+ };
+
+ private SkillDao skillDao;
+ private EmployeeDao employeeDao;
+
+ public void setSkillDao(SkillDao skillDao) {
+ this.skillDao = skillDao;
+ }
+
+ public void setEmployeeDao(EmployeeDao employeeDao) {
+ this.employeeDao = employeeDao;
+ }
+
+ protected void addTestSkills() {
+ try {
+ for (int i = 0, j = TEST_SKILLS.length; i < j; i++) {
+ skillDao.merge(TEST_SKILLS[i]);
+ }
+ if (log.isInfoEnabled()) {
+ log.info("TestDataProvider - [addTestSkills]: Added test skill data.");
+ }
+ } catch (StorageException e) {
+ log.error("TestDataProvider - [addTestSkills]: Exception catched: " + e.getMessage());
+ }
+ }
+
+ protected void addTestEmployees() {
+ try {
+ for (int i = 0, j = TEST_EMPLOYEES.length; i < j; i++) {
+ employeeDao.merge(TEST_EMPLOYEES[i]);
+ }
+ if (log.isInfoEnabled()) {
+ log.info("TestDataProvider - [addTestEmployees]: Added test employee data.");
+ }
+ } catch (StorageException e) {
+ log.error("TestDataProvider - [addTestEmployees]: Exception catched: " + e.getMessage());
+ }
+ }
+
+ protected void addTestData() {
+ addTestSkills();
+ addTestEmployees();
+ }
+
+ public void afterPropertiesSet() throws Exception {
+ addTestData();
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatAuthenticationInterceptor.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatAuthenticationInterceptor.java
new file mode 100644
index 000000000..8c934df1d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatAuthenticationInterceptor.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.dispatcher.SessionMap;
+
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.Interceptor;
+
+public class ChatAuthenticationInterceptor implements Interceptor {
+
+ private static final long serialVersionUID = 1L;
+
+ private static final Log _log = LogFactory.getLog(ChatAuthenticationInterceptor.class);
+
+ public static final String USER_SESSION_KEY = "chatUserSessionKey";
+
+ public void destroy() {
+ }
+
+ public void init() {
+ }
+
+ public String intercept(ActionInvocation invocation) throws Exception {
+
+ _log.debug("Authenticating chat user");
+
+ SessionMap session = (SessionMap) ActionContext.getContext().get(ActionContext.SESSION);
+ User user = (User) session.get(USER_SESSION_KEY);
+
+ if (user == null) {
+ return Action.LOGIN;
+ }
+ return invocation.invoke();
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatException.java
new file mode 100644
index 000000000..0207d6192
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatException.java
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+public class ChatException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ public enum ErrorType {
+ ROOM_ALREADY_EXISTS,
+ USER_ALREADY_EXISTS,
+ NO_SUCH_ROOM_EXISTS
+ }
+
+ public ChatException(String description, ErrorType type) {
+ super(description);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatInterceptor.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatInterceptor.java
new file mode 100644
index 000000000..791aeed43
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatInterceptor.java
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.opensymphony.xwork2.Action;
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionInvocation;
+import com.opensymphony.xwork2.interceptor.Interceptor;
+
+/**
+ * Authenticate showcase chat example, make sure everyone have a username.
+ */
+public class ChatInterceptor implements Interceptor {
+
+ private static final Log _log = LogFactory.getLog(ChatInterceptor.class);
+
+ private static final long serialVersionUID = 1L;
+
+ public static final String CHAT_USER_SESSION_KEY = "ChatUserSessionKey";
+
+ public void destroy() {
+ }
+
+ public void init() {
+ }
+
+ public String intercept(ActionInvocation invocation) throws Exception {
+ HttpSession session = (HttpSession) ActionContext.getContext().get(ActionContext.SESSION);
+ User chatUser = (User) session.getAttribute(CHAT_USER_SESSION_KEY);
+ if (chatUser == null) {
+ _log.debug("Chat user not logged in");
+ return Action.LOGIN;
+ }
+ return invocation.invoke();
+ }
+}
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLoginAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLoginAction.java
new file mode 100644
index 000000000..28450a7c8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLoginAction.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class ChatLoginAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 1L;
+
+ private ChatService chatService;
+ private Map session;
+
+ private String name;
+
+ public ChatLoginAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public String execute() throws Exception {
+ try {
+ chatService.login(new User(name));
+ session.put(ChatAuthenticationInterceptor.USER_SESSION_KEY, new User(name));
+ }
+ catch(ChatException e) {
+ e.printStackTrace();
+ addActionError(e.getMessage());
+ return INPUT;
+ }
+ return SUCCESS;
+ }
+
+
+ // === SessionAware ===
+ public void setSession(Map session) {
+ this.session = session;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLogoutAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLogoutAction.java
new file mode 100644
index 000000000..7f2d326f6
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatLogoutAction.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class ChatLogoutAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 1L;
+
+ private ChatService chatService;
+
+ private Map session;
+
+
+ public ChatLogoutAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String execute() throws Exception {
+
+ User user = (User) session.get(ChatAuthenticationInterceptor.USER_SESSION_KEY);
+ if (user != null) {
+ chatService.logout(user.getName());
+ session.remove(ChatAuthenticationInterceptor.USER_SESSION_KEY);
+ }
+
+ return SUCCESS;
+ }
+
+
+ // === SessionAware ===
+ public void setSession(Map session) {
+ this.session = session;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatMessage.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatMessage.java
new file mode 100644
index 000000000..f2828b818
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatMessage.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.Date;
+
+public class ChatMessage {
+
+ private Date creationDate;
+ private String message;
+ private User creator;
+
+ public ChatMessage(String message, User creator) {
+ assert(message != null);
+ assert(creator != null);
+
+ this.creationDate = new Date(System.currentTimeMillis());
+ this.message = message;
+ this.creator = creator;
+ }
+
+ public Date getCreationDate() {
+ return creationDate;
+ }
+ public User getCreator() {
+ return creator;
+ }
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatService.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatService.java
new file mode 100644
index 000000000..91e31ab8a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatService.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.List;
+
+public interface ChatService {
+ List getAvailableUsers();
+ void login(User user);
+ void logout(String name);
+
+ List getAvailableRooms();
+ void addRoom(Room room);
+ void enterRoom(User user, String roomName);
+ void exitRoom(String userName, String roomName);
+ List getMessagesInRoom(String roomName);
+ void sendMessageToRoom(String roomName, User user, String message);
+ List getUsersAvailableInRoom(String roomName);
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatServiceImpl.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatServiceImpl.java
new file mode 100644
index 000000000..3f90971ac
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatServiceImpl.java
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ChatServiceImpl implements ChatService {
+
+ private Map availableUsers = new LinkedHashMap();
+ private Map availableRooms = new LinkedHashMap();
+
+
+ public List getAvailableUsers() {
+ return new ArrayList(availableUsers.values());
+ }
+
+ public List getAvailableRooms() {
+ return new ArrayList(availableRooms.values());
+ }
+
+ public void addRoom(Room room) {
+ if (availableRooms.containsKey(room.getName())) {
+ throw new ChatException("room ["+room.getName()+"] is already available", ChatException.ErrorType.valueOf("ROOM_ALREADY_EXISTS"));
+ }
+ availableRooms.put(room.getName(), room);
+ }
+
+ public void login(User user) {
+ assert(user != null);
+ if (availableUsers.containsKey(user.getName())) {
+ throw new ChatException("User ["+user.getName()+"] already exists", ChatException.ErrorType.valueOf("USER_ALREADY_EXISTS"));
+ }
+ availableUsers.put(user.getName(), user);
+ }
+
+ public void logout(String name) {
+ assert(name != null);
+ assert(name.trim().length() > 0);
+ availableUsers.remove(name);
+ for (Room room : availableRooms.values()) {
+ if (room.hasMember(name)) {
+ room.memberExit(name);
+ }
+ }
+ }
+
+ public void exitRoom(String userName, String roomName) {
+ assert(roomName != null);
+ assert(roomName.trim().length()> 0);
+
+ if (availableRooms.containsKey(roomName)) {
+ Room room = availableRooms.get(roomName);
+ room.memberExit(userName);
+ }
+ }
+
+ public void enterRoom(User user, String roomName) {
+ assert(roomName != null);
+ assert(roomName.trim().length() > 0);
+ if (! availableRooms.containsKey(roomName)) {
+ throw new ChatException("No such room exists ["+roomName+"]", ChatException.ErrorType.NO_SUCH_ROOM_EXISTS);
+ }
+ Room room = availableRooms.get(roomName);
+ room.memberEnter(user);
+ }
+
+ public List getMessagesInRoom(String roomName) {
+ assert(roomName != null);
+ assert(roomName.trim().length() > 0);
+ if (! availableRooms.containsKey(roomName)) {
+ throw new ChatException("No such room exists ["+roomName+"]", ChatException.ErrorType.NO_SUCH_ROOM_EXISTS);
+ }
+ Room room = availableRooms.get(roomName);
+ return room.getChatMessages();
+ }
+
+ public void sendMessageToRoom(String roomName, User user, String message) {
+ assert(roomName != null);
+ if (! availableRooms.containsKey(roomName)) {
+ throw new ChatException("No such room exists ["+roomName+"]", ChatException.ErrorType.NO_SUCH_ROOM_EXISTS);
+ }
+ Room room = availableRooms.get(roomName);
+ room.addMessage(new ChatMessage(message, user));
+ }
+
+ public List getUsersAvailableInRoom(String roomName) {
+ assert(roomName != null);
+ if (! availableRooms.containsKey(roomName)) {
+ throw new ChatException("No such room exists ["+roomName+"]", ChatException.ErrorType.NO_SUCH_ROOM_EXISTS);
+ }
+ Room room = availableRooms.get(roomName);
+ return room.getMembers();
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatSessionListener.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatSessionListener.java
new file mode 100644
index 000000000..57acc1461
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ChatSessionListener.java
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.context.support.WebApplicationContextUtils;
+
+public class ChatSessionListener implements HttpSessionListener {
+
+ private static final Log _log = LogFactory.getLog(ChatSessionListener.class);
+
+ public void sessionCreated(HttpSessionEvent event) {
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ HttpSession session = event.getSession();
+ WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
+ if (context != null) {
+ User user = (User) session.getAttribute(ChatInterceptor.CHAT_USER_SESSION_KEY);
+ if (user != null) {
+ ChatService service = (ChatService) context.getBean("chatService");
+ service.logout(user.getName());
+
+ _log.info("session expired, logged user ["+user.getName()+"] out");
+ }
+ }
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Constants.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Constants.java
new file mode 100644
index 000000000..59435246e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Constants.java
@@ -0,0 +1,22 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+public class Constants {
+ public static String UPDATE_FREQ = "30000";
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/CrudRoomAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/CrudRoomAction.java
new file mode 100644
index 000000000..307742720
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/CrudRoomAction.java
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class CrudRoomAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private ChatService chatService;
+
+ private String name;
+ private String description;
+
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public CrudRoomAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String create() throws Exception {
+ try {
+ chatService.addRoom(new Room(name, description));
+ }
+ catch(ChatException e) {
+ addActionError(e.getMessage());
+ }
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/DateConverter.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/DateConverter.java
new file mode 100644
index 000000000..d2c89ae35
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/DateConverter.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.util.StrutsTypeConverter;
+
+public class DateConverter extends StrutsTypeConverter {
+
+ private static final Log _log = LogFactory.getLog(DateConverter.class);
+
+ public Object convertFromString(Map context, String[] values, Class toClass) {
+
+ if (values.length > 0 && values[0] != null && values[0].trim().length() > 0) {
+ SimpleDateFormat sdf = new SimpleDateFormat();
+ try {
+ return sdf.parse(values[0]);
+ }
+ catch(ParseException e) {
+ _log.error("error converting value ["+values[0]+"] to Date ", e);
+ }
+ }
+ return null;
+ }
+
+ public String convertToString(Map context, Object o) {
+
+ if (o instanceof Date) {
+ SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
+ return sdf.format((Date) o);
+ }
+ return "";
+ }
+}
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/EnterRoomAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/EnterRoomAction.java
new file mode 100644
index 000000000..707e3b5b1
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/EnterRoomAction.java
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class EnterRoomAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 1L;
+
+ private ChatService chatService;
+ private Map session;
+ private String roomName;
+
+ public String getRoomName() { return this.roomName; }
+ public void setRoomName(String roomName) { this.roomName = roomName; }
+
+ public EnterRoomAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String execute() throws Exception {
+
+ User user = (User) session.get(ChatAuthenticationInterceptor.USER_SESSION_KEY);
+ try {
+ chatService.enterRoom(user, roomName);
+ }
+ catch(Exception e) {
+ addActionError(e.getMessage());
+ }
+ return SUCCESS;
+ }
+
+
+ // === SessionAware ===
+ public void setSession(Map session) {
+ this.session = session;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ExitRoomAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ExitRoomAction.java
new file mode 100644
index 000000000..2ff90a5f9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/ExitRoomAction.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class ExitRoomAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 1L;
+
+ private String roomName;
+
+ private Map session;
+
+ public String getRoomName() { return roomName; }
+ public void setRoomName(String roomName) { this.roomName = roomName; }
+
+ private ChatService chatService;
+
+ public ExitRoomAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String execute() throws Exception {
+ User user = (User) session.get(ChatAuthenticationInterceptor.USER_SESSION_KEY);
+ chatService.exitRoom(user.getName(), roomName);
+
+ return SUCCESS;
+ }
+
+ // === SessionAware ===
+ public void setSession(Map session) {
+ this.session = session;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/MessagesAvailableInRoomAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/MessagesAvailableInRoomAction.java
new file mode 100644
index 000000000..427a2b9ee
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/MessagesAvailableInRoomAction.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class MessagesAvailableInRoomAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private String roomName;
+ private ChatService chatService;
+ private List messagesAvailableInRoom = new ArrayList();
+
+ public String getRoomName() { return this.roomName; }
+ public void setRoomName(String roomName) {
+ this.roomName = roomName;
+ }
+
+ public List getMessagesAvailableInRoom() {
+ return messagesAvailableInRoom;
+ }
+
+ public MessagesAvailableInRoomAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String execute() throws Exception {
+ try {
+ messagesAvailableInRoom = chatService.getMessagesInRoom(roomName);
+ }
+ catch(ChatException e) {
+ addActionError(e.getMessage());
+ }
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Room.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Room.java
new file mode 100644
index 000000000..9ab85da73
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/Room.java
@@ -0,0 +1,98 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Room {
+
+ private static final int MAX_CHAT_MESSAGES = 10;
+
+ private String name;
+ private String description;
+ private Date creationDate;
+
+ private List messages = new ArrayList();
+
+ private Map members = new LinkedHashMap();
+
+ public Room(String name, String description) {
+ this.name = name;
+ this.description = description;
+ this.creationDate = new Date(System.currentTimeMillis());
+ }
+
+
+ // properties
+ public Date getCreationDate() {
+ return creationDate;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+
+ // (behaviour) members
+ public List getMembers() {
+ return new ArrayList(members.values());
+ }
+ public User findMember(String name) {
+ assert(name != null);
+ return members.get(name);
+ }
+ public boolean hasMember(String name) {
+ assert(name != null);
+ return members.containsKey(name);
+ }
+ public void memberEnter(User member) {
+ assert(member != null);
+ if (! hasMember(member.getName())) {
+ members.put(member.getName(), member);
+ }
+ }
+
+ public void memberExit(String memberName) {
+ assert(memberName != null);
+ assert(memberName.trim().length() > 0);
+ members.remove(memberName);
+ }
+
+
+ // (behaviour) chat messags
+ public void addMessage(ChatMessage chatMessage) {
+ if (messages.size() > MAX_CHAT_MESSAGES) {
+ // messages.remove(messages.size() - 1);
+ messages.remove(0);
+ }
+ messages.add(chatMessage);
+ }
+
+ public List getChatMessages() {
+ return new ArrayList(messages);
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/RoomsAvailableAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/RoomsAvailableAction.java
new file mode 100644
index 000000000..111420bd7
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/RoomsAvailableAction.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class RoomsAvailableAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private List availableRooms = new ArrayList();
+
+ private ChatService chatService;
+
+ public RoomsAvailableAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String execute() throws Exception {
+ availableRooms = chatService.getAvailableRooms();
+ return SUCCESS;
+ }
+
+ public List getAvailableRooms() {
+ return availableRooms;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/SendMessageToRoomAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/SendMessageToRoomAction.java
new file mode 100644
index 000000000..42875d78d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/SendMessageToRoomAction.java
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class SendMessageToRoomAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 1L;
+
+ private ChatService chatService;
+
+ private String roomName;
+ private String message;
+ private Map session;
+
+
+ public SendMessageToRoomAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String getRoomName() { return this.roomName; }
+ public void setRoomName(String roomName) {
+ this.roomName = roomName;
+ }
+
+ public String getMessage() { return this.message; }
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+
+ public String execute() throws Exception {
+ User user = (User) session.get(ChatAuthenticationInterceptor.USER_SESSION_KEY);
+ try {
+ chatService.sendMessageToRoom(roomName, user, message);
+ }catch(ChatException e) {
+ addActionError(e.getMessage());
+ }
+ return SUCCESS;
+ }
+
+ public void setSession(Map session) {
+ this.session = session;
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/User.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/User.java
new file mode 100644
index 000000000..8ca098d62
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/User.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Represends a user in the Chat example.
+ */
+public class User implements Serializable {
+
+ private static final long serialVersionUID = -1434958919516089297L;
+
+ private String name;
+ private Date creationDate;
+
+
+ public User(String name) {
+ this.name = name;
+ this.creationDate = new Date(System.currentTimeMillis());
+ }
+
+ public Date getCreationDate() {
+ return creationDate;
+ }
+ public String getName() {
+ return name;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableAction.java
new file mode 100644
index 000000000..82886fe06
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableAction.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class UsersAvailableAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private List availableUsers = new ArrayList();
+ private ChatService chatService;
+
+ public UsersAvailableAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+ public String execute() throws Exception {
+
+ availableUsers = chatService.getAvailableUsers();
+
+ return SUCCESS;
+ }
+
+ public List getAvailableUsers() {
+ return availableUsers;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableInRoomAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableInRoomAction.java
new file mode 100644
index 000000000..96db8aae8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/chat/UsersAvailableInRoomAction.java
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.chat;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class UsersAvailableInRoomAction extends ActionSupport {
+
+ private static final long serialVersionUID = 1L;
+
+ private ChatService chatService;
+ private List usersAvailableInRoom = new ArrayList();
+
+ private String roomName;
+
+ public UsersAvailableInRoomAction(ChatService chatService) {
+ this.chatService = chatService;
+ }
+
+
+ public String getRoomName() { return this.roomName; }
+ public void setRoomName(String roomName) {
+ this.roomName = roomName;
+ }
+
+ public List getUsersAvailableInRoom() {
+ return usersAvailableInRoom;
+ }
+
+ public String execute() throws Exception {
+ try {
+ usersAvailableInRoom = chatService.getUsersAvailableInRoom(roomName);
+ }
+ catch(ChatException e) {
+ addActionError(e.getMessage());
+ }
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Address.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Address.java
new file mode 100644
index 000000000..bf501834e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Address.java
@@ -0,0 +1,35 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+
+/**
+ * @version $Date$ $Id$
+ */
+public class Address {
+
+ private String id;
+ private String address;
+
+ public String getId() { return id; }
+ public void setId(String id) { this.id = id; }
+
+ public String getAddress() { return address; }
+ public void setAddress(String address) { this.address = address; }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction-conversion.properties
new file mode 100644
index 000000000..1a6d70055
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction-conversion.properties
@@ -0,0 +1,6 @@
+
+KeyProperty_addresses=id
+Element_addresses=org.apache.struts2.showcase.conversion.Address
+CreateIfNull_addresses=true
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction.java
new file mode 100644
index 000000000..35f17f5fd
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/AddressAction.java
@@ -0,0 +1,44 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * @version $Date$ $Id$
+ */
+public class AddressAction extends ActionSupport {
+
+ private Set addresses = new LinkedHashSet();
+
+ public Set getAddresses() { return addresses; }
+ public void setAddresses(Set addresses) { this.addresses = addresses; }
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ System.out.println(addresses);
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/EnumTypeConverter.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/EnumTypeConverter.java
new file mode 100644
index 000000000..0a1b1aa38
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/EnumTypeConverter.java
@@ -0,0 +1,55 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.struts2.util.StrutsTypeConverter;
+
+/**
+ * @version $Date$ $Id$
+ */
+public class EnumTypeConverter extends StrutsTypeConverter {
+
+ @Override
+ public Object convertFromString(Map context, String[] values, Class toClass) {
+ List result = new ArrayList();
+ for (int a=0; a< values.length; a++) {
+ Enum e = Enum.valueOf(OperationsEnum.class, values[a]);
+ if (e != null)
+ result.add(e);
+ }
+ return result;
+ }
+
+ @Override
+ public String convertToString(Map context, Object o) {
+ List l = (List) o;
+ String result ="<";
+ for (Iterator i = l.iterator(); i.hasNext(); ) {
+ result = result + "["+ i.next() +"]";
+ }
+ result = result+">";
+ return result;
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnum.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnum.java
new file mode 100644
index 000000000..2db119448
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnum.java
@@ -0,0 +1,30 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+/**
+ *
+ * @version $Date$ $Id$
+ */
+public enum OperationsEnum {
+ ADD,
+ MINUS,
+ DIVIDE,
+ MULTIPLY,
+ REMAINDER;
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction-conversion.properties
new file mode 100644
index 000000000..621beafba
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction-conversion.properties
@@ -0,0 +1,4 @@
+
+selectedOperations=org.apache.struts2.showcase.conversion.EnumTypeConverter
+Element_selectedOperations=org.apache.struts2.showcase.conversion.OperationsEnum
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction.java
new file mode 100644
index 000000000..ee2327ff3
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/OperationsEnumAction.java
@@ -0,0 +1,53 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ * @version $Date$ $Id$
+ */
+public class OperationsEnumAction extends ActionSupport {
+
+ private static final long serialVersionUID = -2229489704988870318L;
+
+ private List selectedOperations = new LinkedList();
+
+ public List getSelectedOperations() { return this.selectedOperations; }
+ public void setSelectedOperations(List selectedOperations) {
+ this.selectedOperations = selectedOperations;
+ }
+
+
+ public List getAvailableOperations() {
+ return Arrays.asList(OperationsEnum.values());
+ }
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Person.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Person.java
new file mode 100644
index 000000000..f87072c11
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/Person.java
@@ -0,0 +1,34 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.io.Serializable;
+
+/**
+ *
+ */
+public class Person implements Serializable {
+ private String name;
+ private Integer age;
+
+ public void setName(String name) { this.name = name; }
+ public String getName() { return this.name; }
+
+ public void setAge(Integer age) { this.age = age; }
+ public Integer getAge() { return this.age; }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties
new file mode 100644
index 000000000..12f602f16
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties
@@ -0,0 +1 @@
+Element_persons=org.apache.struts2.showcase.conversion.Person
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction.java
new file mode 100644
index 000000000..1e0bd55e3
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/conversion/PersonAction.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ */
+public class PersonAction extends ActionSupport {
+
+ private List persons;
+
+ public List getPersons() { return persons; }
+ public void setPersons(List persons) { this.persons = persons; }
+
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/AbstractDao.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/AbstractDao.java
new file mode 100644
index 000000000..3c61468a1
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/AbstractDao.java
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.dao;
+
+import org.apache.struts2.showcase.model.IdEntity;
+import org.apache.struts2.showcase.exception.CreateException;
+import org.apache.struts2.showcase.exception.UpdateException;
+import org.apache.struts2.showcase.exception.StorageException;
+import org.apache.struts2.showcase.application.Storage;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * AbstractDao.
+ *
+ */
+
+public abstract class AbstractDao implements Serializable, Dao {
+
+ private Storage storage;
+
+ public Storage getStorage() {
+ return storage;
+ }
+
+ public void setStorage(Storage storage) {
+ this.storage = storage;
+ }
+
+ public IdEntity get(Serializable id) {
+ return getStorage().get(getFeaturedClass(), id);
+ }
+
+ public Serializable create(IdEntity object) throws CreateException {
+ return getStorage().create(object);
+ }
+
+ public IdEntity update(IdEntity object) throws UpdateException {
+ return getStorage().update(object);
+ }
+
+ public Serializable merge(IdEntity object) throws StorageException {
+ return getStorage().merge(object);
+ }
+
+ public int delete(Serializable id) throws CreateException {
+ return getStorage().delete(getFeaturedClass(), id);
+ }
+
+ public int delete(IdEntity object) throws CreateException {
+ return getStorage().delete(object);
+ }
+
+ public Collection findAll() {
+ return getStorage().findAll(getFeaturedClass());
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/Dao.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/Dao.java
new file mode 100644
index 000000000..c27eb7ade
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/Dao.java
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.dao;
+
+import org.apache.struts2.showcase.model.IdEntity;
+import org.apache.struts2.showcase.exception.CreateException;
+import org.apache.struts2.showcase.exception.UpdateException;
+import org.apache.struts2.showcase.exception.StorageException;
+
+import java.io.Serializable;
+import java.util.Collection;
+
+/**
+ * Dao. Interface.
+ *
+ */
+
+public interface Dao {
+
+ Class getFeaturedClass();
+
+ IdEntity get(Serializable id);
+
+ Serializable create(IdEntity object) throws CreateException;
+
+ IdEntity update(IdEntity object) throws UpdateException;
+
+ Serializable merge(IdEntity object) throws StorageException;
+
+ int delete(Serializable id) throws CreateException;
+
+ int delete(IdEntity object) throws CreateException;
+
+ Collection findAll();
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/EmployeeDao.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/EmployeeDao.java
new file mode 100644
index 000000000..392dcc86f
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/EmployeeDao.java
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.dao;
+
+import org.apache.struts2.showcase.model.Employee;
+import org.apache.struts2.showcase.model.Skill;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * EmployeeDao.
+ *
+ */
+
+public class EmployeeDao extends AbstractDao {
+
+ private static final long serialVersionUID = -6615310540042830594L;
+
+ protected SkillDao skillDao;
+
+ public void setSkillDao(SkillDao skillDao) {
+ this.skillDao = skillDao;
+ }
+
+ public Class getFeaturedClass() {
+ return Employee.class;
+ }
+
+ public Employee getEmployee( Long id ) {
+ return (Employee) get(id);
+ }
+
+ public Employee setSkills(Employee employee, List skillNames) {
+ if (employee!= null && skillNames != null) {
+ employee.setOtherSkills(new ArrayList());
+ for (int i = 0, j = skillNames.size(); i < j; i++) {
+ Skill skill = (Skill) skillDao.get((String) skillNames.get(i));
+ employee.getOtherSkills().add(skill);
+ }
+ }
+ return employee;
+ }
+
+ public Employee setSkills(Long empId, List skillNames) {
+ return setSkills((Employee) get(empId), skillNames);
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/SkillDao.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/SkillDao.java
new file mode 100644
index 000000000..d21a3b48d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/dao/SkillDao.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.dao;
+
+import org.apache.struts2.showcase.model.Skill;
+
+/**
+ * SkillDao.
+ *
+ */
+
+public class SkillDao extends AbstractDao {
+
+ private static final long serialVersionUID = -8160406514074630866L;
+
+ public Class getFeaturedClass() {
+ return Skill.class;
+ }
+
+ public Skill getSkill( String name ) {
+ return (Skill) get(name);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/CreateException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/CreateException.java
new file mode 100644
index 000000000..fbf8b93fc
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/CreateException.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.exception;
+
+/**
+ * CreateException.
+ *
+ */
+
+public class CreateException extends StorageException {
+
+ private static final long serialVersionUID = 6734349565111633783L;
+
+ public CreateException(String message) {
+ super(message);
+ }
+
+ public CreateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public CreateException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DeleteException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DeleteException.java
new file mode 100644
index 000000000..86022d1b5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DeleteException.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.exception;
+
+/**
+ * DeleteException.
+ *
+ */
+
+public class DeleteException extends StorageException {
+
+ private static final long serialVersionUID = -5286362812955627352L;
+
+ public DeleteException(String message) {
+ super(message);
+ }
+
+ public DeleteException(Throwable cause) {
+ super(cause);
+ }
+
+ public DeleteException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DuplicateKeyException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DuplicateKeyException.java
new file mode 100644
index 000000000..4085de5b8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/DuplicateKeyException.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.exception;
+
+/**
+ * DuplicateKeyException.
+ *
+ */
+
+public class DuplicateKeyException extends CreateException {
+
+ private static final long serialVersionUID = 989620752592415898L;
+
+ public DuplicateKeyException(String message) {
+ super(message);
+ }
+
+ public DuplicateKeyException(Throwable cause) {
+ super(cause);
+ }
+
+ public DuplicateKeyException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/StorageException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/StorageException.java
new file mode 100644
index 000000000..d40397c17
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/StorageException.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.exception;
+
+/**
+ * StorageException.
+ *
+ */
+
+public class StorageException extends Exception {
+
+ private static final long serialVersionUID = -2528721270540362905L;
+
+ public StorageException(String message) {
+ super(message);
+ }
+
+ public StorageException(Throwable cause) {
+ super(cause);
+ }
+
+ public StorageException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/UpdateException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/UpdateException.java
new file mode 100644
index 000000000..bb9304b94
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/exception/UpdateException.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.exception;
+
+
+/**
+ * UpdateException.
+ *
+ */
+
+public class UpdateException extends StorageException {
+
+ private static final long serialVersionUID = -4728238600375630452L;
+
+
+ public UpdateException(String message) {
+ super(message);
+ }
+
+ public UpdateException(Throwable cause) {
+ super(cause);
+ }
+
+ public UpdateException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/filedownload/FileDownloadAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/filedownload/FileDownloadAction.java
new file mode 100644
index 000000000..51040156d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/filedownload/FileDownloadAction.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.filedownload;
+
+import org.apache.struts2.ServletActionContext;
+import com.opensymphony.xwork2.Action;
+
+import java.io.InputStream;
+
+/**
+ * Action to demonstrate how to use file download.
+ *
+ * This action is used to download a jpeg file from the image folder.
+ *
+ */
+public class FileDownloadAction implements Action {
+
+ public InputStream getImageStream() throws Exception {
+ return ServletActionContext.getServletContext().getResourceAsStream("/images/struts.gif");
+ }
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/FileUploadAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/FileUploadAction.java
new file mode 100644
index 000000000..3d2906a38
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/fileupload/FileUploadAction.java
@@ -0,0 +1,82 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.fileupload;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+import java.io.File;
+
+/**
+ * Show case File Upload example's action. FileUploadAction
+ *
+ */
+public class FileUploadAction extends ActionSupport {
+
+ private static final long serialVersionUID = 5156288255337069381L;
+
+ private String contentType;
+ private File upload;
+ private String fileName;
+ private String caption;
+
+ // since we are using the file name will be
+ // obtained through getter/setter of FileName
+ public String getUploadFileName() {
+ return fileName;
+ }
+ public void setUploadFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+
+ // since we are using the content type will be
+ // obtained through getter/setter of ContentType
+ public String getUploadContentType() {
+ return contentType;
+ }
+ public void setUploadContentType(String contentType) {
+ this.contentType = contentType;
+ }
+
+
+ // since we are using the File itself will be
+ // obtained through getter/setter of
+ public File getUpload() {
+ return upload;
+ }
+ public void setUpload(File upload) {
+ this.upload = upload;
+ }
+
+
+ public String getCaption() {
+ return caption;
+ }
+ public void setCaption(String caption) {
+ this.caption = caption;
+ }
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String upload() throws Exception {
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManager.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManager.java
new file mode 100644
index 000000000..40b685307
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManager.java
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.freemarker;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.freemarker.FreemarkerManager;
+import org.apache.struts2.views.freemarker.ScopesHashModel;
+
+import com.opensymphony.xwork2.util.OgnlValueStack;
+
+/**
+ * This is an example of a custom FreemarkerManager, mean to be
+ * instantiated through Spring.
+ *
+ *
+ * It will add into Freemarker's model
+ * an utility class called {@link CustomFreemarkerManagerUtil} as a simple
+ * example demonstrating how to extends FreemarkerManager.
+ *
+ *
+ * The {@link CustomFreemarkerManagerUtil} will be created by Spring and
+ * injected through constructor injection.
+ *
+ */
+public class CustomFreemarkerManager extends FreemarkerManager {
+
+ private CustomFreemarkerManagerUtil util;
+
+ public CustomFreemarkerManager(CustomFreemarkerManagerUtil util) {
+ this.util = util;
+ }
+
+ public void populateContext(ScopesHashModel model, OgnlValueStack stack, Object action, HttpServletRequest request, HttpServletResponse response) {
+ super.populateContext(model, stack, action, request, response);
+ model.put("customFreemarkerManagerUtil", util);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManagerUtil.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManagerUtil.java
new file mode 100644
index 000000000..f27079e1e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/freemarker/CustomFreemarkerManagerUtil.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.freemarker;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * This class is just a simple util that gets injected into
+ * {@link CustomFreemarkerManager} through Spring's constructor
+ * injection, serving as a simple example in Struts' Showcase.
+ */
+public class CustomFreemarkerManagerUtil {
+
+ public String getTodayDate() {
+ SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
+ return sdf.format(new Date());
+ }
+
+ public String getTimeNow() {
+ SimpleDateFormat sdf = new SimpleDateFormat("hh:mm:ss");
+ return sdf.format(new Date());
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GetUpdatedHangmanAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GetUpdatedHangmanAction.java
new file mode 100644
index 000000000..9e5ec7055
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GetUpdatedHangmanAction.java
@@ -0,0 +1,39 @@
+package org.apache.struts2.showcase.hangman;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class GetUpdatedHangmanAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 5506025785406043027L;
+
+ private Map session;
+ private Hangman hangman;
+
+
+ public String execute() throws Exception {
+ hangman = (Hangman) session.get(HangmanConstants.HANGMAN_SESSION_KEY);
+
+ System.out.println("\n\n\n");
+ System.out.println("hangman="+hangman);
+ System.out.println("available = "+hangman.getCharactersAvailable().size());
+ System.out.println("guess left="+hangman.guessLeft());
+ System.out.println("\n\n\n");
+
+ return SUCCESS;
+ }
+
+ public void setSession(Map session) {
+ this.session = session;
+ }
+
+ public Hangman getHangman() {
+ return hangman;
+ }
+ public void setHangman(Hangman hangman) {
+ this.hangman = hangman;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GuessCharacterAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GuessCharacterAction.java
new file mode 100644
index 000000000..aa1851140
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/GuessCharacterAction.java
@@ -0,0 +1,39 @@
+package org.apache.struts2.showcase.hangman;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class GuessCharacterAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 9050915577007590674L;
+
+ private Map session;
+ private Character character;
+ private Hangman hangman;
+
+ public String execute() throws Exception {
+ hangman = (Hangman) session.get(HangmanConstants.HANGMAN_SESSION_KEY);
+ hangman.guess(character);
+
+ return SUCCESS;
+ }
+
+ public Hangman getHangman() {
+ return hangman;
+ }
+
+ public void setSession(Map session) {
+ this.session = session;
+ }
+
+ public void setCharacter(Character character) {
+ this.character = character;
+ }
+
+ public Character getCharacter() {
+ return this.character;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Hangman.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Hangman.java
new file mode 100644
index 000000000..cfbf7a59c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Hangman.java
@@ -0,0 +1,106 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class Hangman implements Serializable {
+
+ private static final long serialVersionUID = 8566954355839652509L;
+
+ private Vocab vocab;
+
+ private Boolean win = false;
+
+ private int guessLeft = 5;
+ public List charactersAvailable;
+ public List charactersGuessed;
+
+ public Hangman(Vocab vocab) {
+ // Arrays.asList(...) returns List that doesn't support remove(), hence
+ // we wrap it with an ArrayList to avoid UnsupportedOperationException
+ // when doing a remove()
+ charactersAvailable = new ArrayList(Arrays.asList(
+ new Character[] {
+ Character.valueOf('A'), Character.valueOf('B'), Character.valueOf('C'),
+ Character.valueOf('D'), Character.valueOf('E'), Character.valueOf('F'),
+ Character.valueOf('G'), Character.valueOf('H'), Character.valueOf('I'),
+ Character.valueOf('J'), Character.valueOf('K'), Character.valueOf('L'),
+ Character.valueOf('M'), Character.valueOf('N'), Character.valueOf('O'),
+ Character.valueOf('P'), Character.valueOf('Q'), Character.valueOf('R'),
+ Character.valueOf('S'), Character.valueOf('T'), Character.valueOf('U'),
+ Character.valueOf('V'), Character.valueOf('W'), Character.valueOf('X'),
+ Character.valueOf('Y'), Character.valueOf('Z')
+ }));
+ charactersGuessed = new ArrayList();
+ this.vocab = vocab;
+ }
+
+ public void guess(Character character) {
+ assert(character != null);
+
+ synchronized(charactersAvailable) {
+ if (guessLeft < 0) {
+ throw new HangmanException(
+ HangmanException.Type.valueOf("GAME_ENDED"), "Game already eneded");
+ }
+ Character characterInUpperCase = Character.toUpperCase(character);
+ boolean ok = charactersAvailable.remove(characterInUpperCase);
+ if (ok) {
+ charactersGuessed.add(characterInUpperCase);
+ if (! vocab.containCharacter(characterInUpperCase)) {
+ guessLeft = guessLeft - 1;
+ }
+ }
+ if (vocab.containsAllCharacter(charactersGuessed)) {
+ win = true;
+ }
+ System.out.println(" *********************************** "+win);
+ }
+ }
+
+ public Boolean isWin() {
+ return this.win;
+ }
+
+ public Vocab getVocab() {
+ return vocab;
+ }
+
+ public Boolean gameEnded() {
+ return ((guessLeft < 0) || win);
+ }
+
+ public Integer guessLeft() {
+ return guessLeft;
+ }
+
+ public List getCharactersAvailable() {
+ synchronized(charactersAvailable) {
+ return new ArrayList(charactersAvailable);
+ //return charactersAvailable;
+ }
+ }
+
+ public boolean characterGuessedBefore(Character character) {
+ return charactersGuessed.contains(character);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanConstants.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanConstants.java
new file mode 100644
index 000000000..2c5fd14a4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanConstants.java
@@ -0,0 +1,6 @@
+package org.apache.struts2.showcase.hangman;
+
+public class HangmanConstants {
+ // keeps a Hangman object in HttpSession
+ public static final String HANGMAN_SESSION_KEY = "Hangman_Session_Key";
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanException.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanException.java
new file mode 100644
index 000000000..95ac17e84
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanException.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+public class HangmanException extends RuntimeException {
+
+ private static final long serialVersionUID = -8500292863595941335L;
+
+ enum Type {
+ GAME_ENDED,
+ NO_VOCAB,
+ NO_VOCAB_SOURCE;
+ }
+
+
+ private Type type;
+
+ public HangmanException (Type type, String reason) {
+ super(reason);
+ this.type = type;
+ }
+
+ public Type getType() {
+ return type;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanService.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanService.java
new file mode 100644
index 000000000..0219bfe34
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/HangmanService.java
@@ -0,0 +1,31 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+public class HangmanService {
+
+ public VocabSource vocabSource;
+
+ public HangmanService(VocabSource vocabSource) {
+ this.vocabSource = vocabSource;
+ }
+
+ public Hangman startNewGame() {
+ return new Hangman(vocabSource.getRandomVocab());
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/PropertiesVocabSource.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/PropertiesVocabSource.java
new file mode 100644
index 000000000..ec3e1a89a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/PropertiesVocabSource.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+public class PropertiesVocabSource implements VocabSource {
+
+ private Properties prop;
+ private List vocabs;
+
+ public PropertiesVocabSource() {
+ }
+
+ public PropertiesVocabSource(Properties prop) {
+ assert(prop != null);
+ this.prop = prop;
+ vocabs = readVocab(prop);
+ }
+
+ public void setVocabProperties(Properties prop) {
+ assert(prop != null);
+ this.prop = prop;
+ vocabs = readVocab(prop);
+ }
+
+ public Vocab getRandomVocab() {
+ if (vocabs == null) {
+ throw new HangmanException(HangmanException.Type.valueOf("NO_VOCAB_SOURCE"), "No vocab source");
+ }
+ if (vocabs.size() <= 0) {
+ throw new HangmanException(HangmanException.Type.valueOf("NO_VOCAB"), "No vocab");
+ }
+ long vocabIndex = Math.round((Math.random() * (double)prop.size()));
+ vocabIndex = vocabIndex == vocabs.size() ? vocabs.size() - 1 : vocabIndex;
+ return vocabs.get((int)vocabIndex);
+ }
+
+ protected List readVocab(Properties prop) {
+ List vocabList = new ArrayList();
+
+ for (Map.Entry e : prop.entrySet()) {
+ String vocab = (String) e.getKey();
+ String hint = (String) e.getValue();
+
+ vocabList.add(new Vocab(vocab, hint));
+ }
+ return vocabList;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/StartHangmanAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/StartHangmanAction.java
new file mode 100644
index 000000000..508874834
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/StartHangmanAction.java
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+import static org.apache.struts2.showcase.hangman.HangmanConstants.*;
+
+import java.util.Map;
+
+import org.apache.struts2.interceptor.SessionAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class StartHangmanAction extends ActionSupport implements SessionAware {
+
+ private static final long serialVersionUID = 2333463075324892521L;
+
+ private HangmanService service;
+ private Hangman hangman;
+ private Map session;
+
+
+ public StartHangmanAction(HangmanService service) {
+ this.service = service;
+ }
+
+ public String execute() throws Exception {
+
+ hangman = service.startNewGame();
+ session.put(HANGMAN_SESSION_KEY, hangman);
+
+ return SUCCESS;
+ }
+
+ public Hangman getHangman() {
+ return hangman;
+ }
+
+
+ // === SessionAware ===
+ public void setSession(Map session) {
+ this.session = session;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Vocab.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Vocab.java
new file mode 100644
index 000000000..b01b4317e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/Vocab.java
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class Vocab implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String vocab;
+ private String hint;
+ private Character[] characters; // character this vocab is made up of
+
+ public Vocab(String vocab, String hint) {
+ assert(vocab != null);
+ assert(hint != null);
+
+ this.vocab = vocab.toUpperCase();
+ this.hint = hint;
+ }
+
+ public String getVocab() { return this.vocab; }
+ public String getHint() { return this.hint; }
+
+ public Boolean containCharacter(Character character) {
+ assert(character != null);
+
+ return (vocab.contains(character.toString())) ? true : false;
+ }
+
+ public Character[] inCharacters() {
+ if (characters == null) {
+ char[] c = vocab.toCharArray();
+ characters = new Character[c.length];
+ for (int a=0; a< c.length; a++) {
+ characters[a] = Character.valueOf(c[a]);
+ }
+ }
+ return characters;
+ }
+
+ public boolean containsAllCharacter(List charactersGuessed) {
+ Character[] chars = inCharacters();
+ List tmpChars = Arrays.asList(chars);
+ return charactersGuessed.containsAll(tmpChars);
+ }
+
+ public static void main(String args[]) throws Exception {
+ Vocab v = new Vocab("JAVA", "a java word");
+
+ List list1= new ArrayList();
+ list1.add(new Character('J'));
+ list1.add(new Character('V'));
+
+ List list2 = new ArrayList();
+ list2.add(new Character('J'));
+ list2.add(new Character('V'));
+ list2.add(new Character('A'));
+
+ System.out.println(v.containsAllCharacter(list1));
+ System.out.println(v.containsAllCharacter(list2));
+
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/VocabSource.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/VocabSource.java
new file mode 100644
index 000000000..4682d81a2
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/hangman/VocabSource.java
@@ -0,0 +1,22 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.hangman;
+
+public interface VocabSource {
+ Vocab getRandomVocab();
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/EditGangsterAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/EditGangsterAction.java
new file mode 100644
index 000000000..49e8d3728
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/EditGangsterAction.java
@@ -0,0 +1,41 @@
+/*
+ * $Id: Gangster.java 418530 2006-07-01 23:58:13Z mrdon $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.integration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+
+public class EditGangsterAction extends Action {
+
+ /* (non-Javadoc)
+ * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
+ // Some code to load the gangster from the db as necessary
+
+ return mapping.findForward("success");
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/GangsterForm.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/GangsterForm.java
new file mode 100644
index 000000000..477135f48
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/GangsterForm.java
@@ -0,0 +1,89 @@
+package org.apache.struts2.showcase.integration;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.struts.action.ActionErrors;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionMessage;
+import org.apache.struts.validator.ValidatorForm;
+
+public class GangsterForm extends ValidatorForm {
+
+ private String name;
+ private String age;
+ private String description;
+ private boolean bustedBefore;
+
+ /* (non-Javadoc)
+ * @see org.apache.struts.action.ActionForm#reset(org.apache.struts.action.ActionMapping, javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public void reset(ActionMapping arg0, HttpServletRequest arg1) {
+ bustedBefore = false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.struts.action.ActionForm#validate(org.apache.struts.action.ActionMapping, javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
+ ActionErrors errors = super.validate(mapping, request);
+ if (name == null || name.length() == 0) {
+ errors.add("name", new ActionMessage("The name must not be blank"));
+ }
+
+ return errors;
+ }
+
+ /**
+ * @return the age
+ */
+ public String getAge() {
+ return age;
+ }
+ /**
+ * @param age the age to set
+ */
+ public void setAge(String age) {
+ this.age = age;
+ }
+ /**
+ * @return the bustedBefore
+ */
+ public boolean isBustedBefore() {
+ return bustedBefore;
+ }
+ /**
+ * @param bustedBefore the bustedBefore to set
+ */
+ public void setBustedBefore(boolean bustedBefore) {
+ this.bustedBefore = bustedBefore;
+ }
+ /**
+ * @return the description
+ */
+ public String getDescription() {
+ return description;
+ }
+ /**
+ * @param description the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+ /**
+ * @param name the name to set
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/SaveGangsterAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/SaveGangsterAction.java
new file mode 100644
index 000000000..86204855a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/integration/SaveGangsterAction.java
@@ -0,0 +1,48 @@
+/*
+ * $Id: Gangster.java 418530 2006-07-01 23:58:13Z mrdon $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.integration;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts.action.Action;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.action.ActionMessage;
+import org.apache.struts.action.ActionMessages;
+
+public class SaveGangsterAction extends Action {
+
+ /* (non-Javadoc)
+ * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @Override
+ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+ // Some code to save the gangster to the db as necessary
+ GangsterForm gform = (GangsterForm) form;
+ ActionMessages messages = new ActionMessages();
+ messages.add("msg", new ActionMessage("Gangster "+gform.getName()+" added successfully"));
+ addMessages(request, messages);
+
+ return mapping.findForward("success");
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/jsf/JsfEmployeeAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/jsf/JsfEmployeeAction.java
new file mode 100644
index 000000000..89f2db5de
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/jsf/JsfEmployeeAction.java
@@ -0,0 +1,119 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.jsf;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.struts2.showcase.action.EmployeeAction;
+import org.apache.struts2.showcase.dao.SkillDao;
+import org.apache.struts2.showcase.model.Employee;
+import org.apache.struts2.showcase.model.Skill;
+
+/**
+ * Overriding the EmployeeAction to main provide getters returning the data in
+ * the form required by the JSF components
+ */
+public class JsfEmployeeAction extends EmployeeAction {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creating a default employee and main skill, since the JSF EL can't handle
+ * creating new objects as necessary
+ *
+ */
+ public JsfEmployeeAction() {
+ Employee e = new Employee();
+ e.setMainSkill(new Skill());
+ setCurrentEmployee(e);
+ }
+
+ private SkillDao skillDao;
+
+ public void setSkillDao(SkillDao skillDao) {
+ this.skillDao = skillDao;
+ }
+
+ /**
+ * Returning a List because the JSF dataGrid can't handle a Set for some
+ * reason
+ */
+ @Override
+ public Collection getAvailableItems() {
+ return new ArrayList(super.getAvailableItems());
+ }
+
+ /**
+ * Changing the String array into a Map
+ */
+ public Map getAvailablePositionsAsMap() {
+ Map map = new LinkedHashMap();
+ for (String val : super.getAvailablePositions()) {
+ map.put(val, val);
+ }
+ return map;
+ }
+
+ /**
+ * Converting the list into a map
+ */
+ public Map getAvailableLevelsAsMap() {
+ Map map = new LinkedHashMap();
+ for (Object val : super.getAvailableLevels()) {
+ map.put(val, val);
+ }
+ return map;
+ }
+
+ /**
+ * Converting the Skill object list into a map
+ */
+ public Map getAvailableSkills() {
+ Map map = new HashMap();
+ for (Object val : skillDao.findAll()) {
+ Skill skill = (Skill) val;
+ map.put(skill.getDescription(), skill.getName());
+ }
+ return map;
+ }
+
+ /**
+ * Gets the selected Skill objects as a list
+ */
+ public List getSelectedSkillsAsList() {
+ System.out.println("asked for skills");
+ List list = new ArrayList();
+ List skills = super.getSelectedSkills();
+ if (skills != null) {
+ for (Object val : skills) {
+ if (val instanceof Skill) {
+ list.add(((Skill) val).getDescription());
+ } else {
+ Skill skill = skillDao.getSkill((String) val);
+ list.add(skill.getDescription());
+ }
+ }
+ }
+ return list;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Employee.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Employee.java
new file mode 100644
index 000000000..9d8ff6208
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Employee.java
@@ -0,0 +1,173 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.model;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Employee.
+ *
+ */
+
+public class Employee implements IdEntity {
+
+ private static final long serialVersionUID = -6226845151026823748L;
+
+ private Long empId; //textfield w/ conversion
+ private String firstName;
+ private String lastName;
+ private Date birthDate; //datepicker
+ private Float salary; //textfield w/ conversion
+ private boolean married; //checkbox
+ private String position; //combobox
+ private Skill mainSkill; //select
+ private List otherSkills; //doubleSelect
+ private String password; //password
+ private String level; //radio
+ private String comment; //textarea
+
+ public Employee() {
+ }
+
+ public Employee(Long empId, String firstName, String lastName) {
+ this.empId = empId;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ }
+
+ public Employee(Long empId, String firstName, String lastName, Date birthDate, Float salary, boolean married, String position, Skill mainSkill, List otherSkills, String password, String level, String comment) {
+ this.empId = empId;
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.birthDate = birthDate;
+ this.salary = salary;
+ this.married = married;
+ this.position = position;
+ this.mainSkill = mainSkill;
+ this.otherSkills = otherSkills;
+ this.password = password;
+ this.level = level;
+ this.comment = comment;
+ }
+
+ public Long getEmpId() {
+ return empId;
+ }
+
+ public void setEmpId(Long empId) {
+ this.empId = empId;
+ }
+
+ public Serializable getId() {
+ return getEmpId();
+ }
+
+ public void setId(Serializable id) {
+ setEmpId((Long) id);
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public Date getBirthDate() {
+ return birthDate;
+ }
+
+ public void setBirthDate(Date birthDate) {
+ this.birthDate = birthDate;
+ }
+
+ public Float getSalary() {
+ return salary;
+ }
+
+ public void setSalary(Float salary) {
+ this.salary = salary;
+ }
+
+ public boolean isMarried() {
+ return married;
+ }
+
+ public void setMarried(boolean married) {
+ this.married = married;
+ }
+
+ public String getPosition() {
+ return position;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public Skill getMainSkill() {
+ return mainSkill;
+ }
+
+ public void setMainSkill(Skill mainSkill) {
+ this.mainSkill = mainSkill;
+ }
+
+ public List getOtherSkills() {
+ return otherSkills;
+ }
+
+ public void setOtherSkills(List otherSkills) {
+ this.otherSkills = otherSkills;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getLevel() {
+ return level;
+ }
+
+ public void setLevel(String level) {
+ this.level = level;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public void setComment(String comment) {
+ this.comment = comment;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/IdEntity.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/IdEntity.java
new file mode 100644
index 000000000..6f43eb831
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/IdEntity.java
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.model;
+
+import java.io.Serializable;
+
+/**
+ * IdEntity. Interface.
+ *
+ */
+
+public interface IdEntity extends Serializable {
+
+ Serializable getId ();
+
+ void setId ( Serializable id );
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Skill.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Skill.java
new file mode 100644
index 000000000..ab2122c84
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/model/Skill.java
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.model;
+
+import java.io.Serializable;
+
+/**
+ * Skill.
+ *
+ */
+
+public class Skill implements IdEntity {
+
+ private static final long serialVersionUID = -4150317722693212439L;
+
+ private String name;
+ private String description;
+
+ public Skill() {
+ }
+
+ public Skill(String name, String description) {
+ this.name = name;
+ this.description = description;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Serializable getId() {
+ return getName();
+ }
+
+ public void setId(Serializable id) {
+ setName((String) id);
+ }
+
+ public String toString() {
+ return getName();
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/Gangster.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/Gangster.java
new file mode 100644
index 000000000..90f0d05f8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/Gangster.java
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.modelDriven;
+
+import java.io.Serializable;
+
+/**
+ * A model class to be used by the simple Model-Driven example.
+ *
+ */
+public class Gangster implements Serializable {
+
+ private static final long serialVersionUID = 3688389475320294992L;
+
+ private String name;
+ private int age;
+ private String description;
+ private boolean bustedBefore;
+
+ public int getAge() {
+ return age;
+ }
+ public void setAge(int age) {
+ this.age = age;
+ }
+ public boolean isBustedBefore() {
+ return bustedBefore;
+ }
+ public void setBustedBefore(boolean bustedBefore) {
+ this.bustedBefore = bustedBefore;
+ }
+ public String getDescription() {
+ return description;
+ }
+ public void setDescription(String description) {
+ this.description = description;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java
new file mode 100644
index 000000000..1484dc567
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/modelDriven/ModelDrivenAction.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.modelDriven;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.ModelDriven;
+
+/**
+ * Action to demonstrate simple model-driven feature of the framework.
+ *
+ */
+public class ModelDrivenAction extends ActionSupport implements ModelDriven {
+
+ private static final long serialVersionUID = 1271130427666936592L;
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+
+ public Object getModel() {
+ return new Gangster();
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson-validation.xml
new file mode 100644
index 000000000..6d19ebdf6
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson-validation.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson.java
new file mode 100644
index 000000000..7e6c63e3e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/CreatePerson.java
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.person;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class CreatePerson extends ActionSupport {
+
+ private static final long serialVersionUID = 200410824352645515L;
+
+ PersonManager personManager;
+ Person person;
+
+ public void setPersonManager(PersonManager personManager) {
+ this.personManager = personManager;
+ }
+
+ public String execute() {
+ personManager.createPerson(person);
+
+ return SUCCESS;
+ }
+
+ public Person getPerson() {
+ return person;
+ }
+
+ public void setPerson(Person person) {
+ this.person = person;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson-conversion.properties
new file mode 100644
index 000000000..00b2a0365
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson-conversion.properties
@@ -0,0 +1,3 @@
+KeyProperty_persons=id
+Element_persons=org.apache.struts2.showcase.person.Person
+CreateIfNull_persons=true
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson.java
new file mode 100644
index 000000000..43db2859e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/EditPerson.java
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.person;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * EditPerson
+ *
+ */
+public class EditPerson extends ActionSupport {
+
+ private static final long serialVersionUID = 7699491775215130850L;
+
+ PersonManager personManager;
+ List persons = new ArrayList();
+
+ public void setPersonManager(PersonManager personManager) {
+ this.personManager = personManager;
+ }
+
+ public List getPersons() {
+ return persons;
+ }
+
+ public void setPersons(List persons) {
+ this.persons = persons;
+ }
+
+ /**
+ * A default implementation that does nothing an returns "success".
+ *
+ * @return {@link #SUCCESS}
+ */
+ public String execute() throws Exception {
+ persons.addAll(personManager.getPeople());
+ return SUCCESS;
+ }
+
+ /**
+ * A default implementation that does nothing an returns "success".
+ *
+ * @return {@link #SUCCESS}
+ */
+ public String save() throws Exception {
+
+ // Set people = personManager.getPeople();
+
+ for ( Iterator iter = persons.iterator(); iter.hasNext();) {
+ Person p = (Person) iter.next();
+ personManager.getPeople().remove(p);
+ personManager.getPeople().add(p);
+ }
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/ListPeople.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/ListPeople.java
new file mode 100644
index 000000000..ca605a7d8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/ListPeople.java
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.person;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ */
+public class ListPeople extends ActionSupport {
+
+ private static final long serialVersionUID = 3608017189783645371L;
+
+ PersonManager personManager;
+ List people = new ArrayList();
+
+ public void setPersonManager(PersonManager personManager) {
+ this.personManager = personManager;
+ }
+
+ public String execute() {
+ people.addAll(personManager.getPeople());
+
+ return SUCCESS;
+ }
+
+ public List getPeople() {
+ return people;
+ }
+
+ public int getPeopleCount() {
+ return people.size();
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person-validation.xml
new file mode 100644
index 000000000..da2c81f0c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person-validation.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ You must enter a first name.
+
+
+
+
+ You must enter a last name
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person.java
new file mode 100644
index 000000000..20cb4d52d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/Person.java
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.person;
+
+/**
+ */
+public class Person {
+ Long id;
+ String name;
+ String lastName;
+
+ public Person() {
+ }
+
+ public Person(Long id, String name, String lastName) {
+ this.id = id;
+ this.name = name;
+ this.lastName = lastName;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ final Person person = (Person) o;
+
+ if (id != null ? !id.equals(person.id) : person.id != null) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ return (id != null ? id.hashCode() : 0);
+ }
+
+
+ public String toString() {
+ return "Person{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ ", lastName='" + lastName + '\'' +
+ '}';
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/PersonManager.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/PersonManager.java
new file mode 100644
index 000000000..1a984b108
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/person/PersonManager.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.person;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ */
+public class PersonManager {
+ private static Set people = new HashSet(5);
+ private static long COUNT = 5;
+
+ static {
+ // create some imaginary persons
+ Person p1 = new Person(new Long(1), "Patrick", "Lightbuddie");
+ Person p2 = new Person(new Long(2), "Jason", "Carrora");
+ Person p3 = new Person(new Long(3), "Alexandru", "Papesco");
+ Person p4 = new Person(new Long(4), "Jay", "Boss");
+ Person p5 = new Person(new Long(5), "Rainer", "Hermanos");
+ people.add(p1);
+ people.add(p2);
+ people.add(p3);
+ people.add(p4);
+ people.add(p5);
+ }
+
+ public void createPerson(Person person) {
+ person.setId(new Long(++COUNT));
+ people.add(person);
+ }
+
+ public void updatePerson(Person person) {
+ people.add(person);
+ }
+
+ public Set getPeople() {
+ return people;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/sitemesh/NoneDecoratorMapper.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/sitemesh/NoneDecoratorMapper.java
new file mode 100644
index 000000000..ad701c3f5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/sitemesh/NoneDecoratorMapper.java
@@ -0,0 +1,20 @@
+package org.apache.struts2.showcase.sitemesh;
+
+import com.opensymphony.module.sitemesh.Decorator;
+import com.opensymphony.module.sitemesh.Page;
+import com.opensymphony.module.sitemesh.mapper.AbstractDecoratorMapper;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * @author Patrick Lightbody (plightbo at gmail dot com)
+ */
+public class NoneDecoratorMapper extends AbstractDecoratorMapper {
+ public Decorator getDecorator(HttpServletRequest req, Page page) {
+ if ("none".equals(req.getAttribute("decorator"))) {
+ return null;
+ }
+
+ return super.getDecorator(req, page);
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java
new file mode 100644
index 000000000..327bfe489
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/source/ViewSourceAction.java
@@ -0,0 +1,217 @@
+/*
+ * $Id: CreatePerson.java 420385 2006-07-10 00:57:05Z mrdon $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.source;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletContext;
+
+import org.apache.struts2.util.ServletContextAware;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.util.ClassLoaderUtil;
+
+/**
+ * Processes configuration, page, and action class paths to create snippets
+ * of the files for display.
+ */
+public class ViewSourceAction extends ActionSupport implements ServletContextAware {
+
+ private String page;
+ private String className;
+ private String config;
+
+ private List pageLines;
+ private List classLines;
+ private List configLines;
+
+ private int configLine;
+ private int padding = 10;
+
+ private ServletContext servletContext;
+
+ public String execute() throws MalformedURLException, IOException {
+
+ if (page != null) {
+
+ InputStream in = ClassLoaderUtil.getResourceAsStream(page.substring(page.indexOf("//")+1), getClass());
+ page = page.replace("//", "/");
+
+ if (in == null) {
+ in = servletContext.getResourceAsStream(page);
+ while (in == null && page.indexOf('/', 1) > 0) {
+ page = page.substring(page.indexOf('/', 1));
+ in = servletContext.getResourceAsStream(page);
+ }
+ }
+ pageLines = read(in, -1);
+ }
+
+ if (className != null) {
+ className = "/"+className.replace('.', '/') + ".java";
+ InputStream in = getClass().getResourceAsStream(className);
+ if (in == null) {
+ in = servletContext.getResourceAsStream("/WEB-INF/src"+className);
+ }
+ classLines = read(in, -1);
+ }
+
+ if (config != null) {
+ int pos = config.lastIndexOf(':');
+ configLine = Integer.parseInt(config.substring(pos+1));
+ config = config.substring(0, pos).replace("//", "/");
+ configLines = read(new URL(config).openStream(), configLine);
+ }
+ return SUCCESS;
+ }
+
+ /**
+ * @param className the className to set
+ */
+ public void setClassName(String className) {
+ this.className = className;
+ }
+
+ /**
+ * @param config the config to set
+ */
+ public void setConfig(String config) {
+ this.config = config;
+ }
+
+ /**
+ * @param page the page to set
+ */
+ public void setPage(String page) {
+ this.page = page;
+ }
+
+ /**
+ * @param padding the padding to set
+ */
+ public void setPadding(int padding) {
+ this.padding = padding;
+ }
+
+
+
+ /**
+ * @return the classLines
+ */
+ public List getClassLines() {
+ return classLines;
+ }
+
+ /**
+ * @return the configLines
+ */
+ public List getConfigLines() {
+ return configLines;
+ }
+
+ /**
+ * @return the pageLines
+ */
+ public List getPageLines() {
+ return pageLines;
+ }
+
+ /**
+ * @return the className
+ */
+ public String getClassName() {
+ return className;
+ }
+
+ /**
+ * @return the config
+ */
+ public String getConfig() {
+ return config;
+ }
+
+ /**
+ * @return the page
+ */
+ public String getPage() {
+ return page;
+ }
+
+ /**
+ * @return the configLine
+ */
+ public int getConfigLine() {
+ return configLine;
+ }
+
+ /**
+ * @return the padding
+ */
+ public int getPadding() {
+ return padding;
+ }
+
+ /**
+ * Reads in a strea, optionally only including the target line number
+ * and its padding
+ *
+ * @param in The input stream
+ * @param targetLineNumber The target line number, negative to read all
+ * @return A list of lines
+ */
+ private List read(InputStream in, int targetLineNumber) {
+ List snippet = null;
+ if (in != null) {
+ snippet = new ArrayList();
+ int startLine = 0;
+ int endLine = Integer.MAX_VALUE;
+ if (targetLineNumber > 0) {
+ startLine = targetLineNumber - padding;
+ endLine = targetLineNumber + padding;
+ }
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+ int lineno = 0;
+ String line;
+ while ((line = reader.readLine()) != null) {
+ lineno++;
+ if (lineno >= startLine && lineno <= endLine) {
+ snippet.add(line);
+ }
+ }
+ } catch (Exception ex) {
+ // ignoring as snippet not available isn't a big deal
+ }
+ }
+ return snippet;
+ }
+
+ public void setServletContext(ServletContext arg0) {
+ this.servletContext = arg0;
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actionPrefix/SubmitAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actionPrefix/SubmitAction.java
new file mode 100644
index 000000000..fb20f27d9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actionPrefix/SubmitAction.java
@@ -0,0 +1,22 @@
+package org.apache.struts2.showcase.tag.nonui.actionPrefix;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class SubmitAction extends ActionSupport {
+
+ private static final long serialVersionUID = -7832803019378213087L;
+
+ private String text;
+
+ public String getText() { return text; }
+ public void setText(String text) { this.text = text; }
+
+ public String execute() throws Exception {
+ return SUCCESS;
+ }
+
+ public String alternateMethod() {
+ return "methodPrefixResult";
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actiontag/ActionTagDemo.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actiontag/ActionTagDemo.java
new file mode 100644
index 000000000..1874adffd
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/actiontag/ActionTagDemo.java
@@ -0,0 +1,35 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.tag.nonui.actiontag;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class ActionTagDemo extends ActionSupport {
+
+ private static final long serialVersionUID = -2749145880590245184L;
+
+ public String show() throws Exception {
+ return SUCCESS;
+ }
+
+ public String doInclude() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/AppendIteratorTagDemo.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/AppendIteratorTagDemo.java
new file mode 100644
index 000000000..b4cc3d033
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/AppendIteratorTagDemo.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.tag.nonui.iteratortag;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.Validateable;
+
+/**
+ *
+ */
+public class AppendIteratorTagDemo extends ActionSupport implements Validateable {
+
+ private static final long serialVersionUID = -6525059998526094664L;
+
+ private String iteratorValue1;
+ private String iteratorValue2;
+
+
+ public void validate() {
+ if (iteratorValue1 == null || iteratorValue1.trim().length() <= 0 ) {
+ addFieldError("iteratorValue1", "iterator value 1 cannot be empty");
+ }
+ else if (iteratorValue1.trim().indexOf(",") <= 0) {
+ addFieldError("iteratorValue1", "iterator value 1 needs to be comma separated");
+ }
+ if (iteratorValue2 == null || iteratorValue2.trim().length() <= 0) {
+ addFieldError("iteratorValue2", "iterator value 2 cannot be empty");
+ }
+ else if (iteratorValue2.trim().indexOf(",") <= 0) {
+ addFieldError("iteratorValue2", "iterator value 2 needs to be comma separated");
+ }
+ }
+
+
+
+
+ public String getIteratorValue1() {
+ return iteratorValue1;
+ }
+ public void setIteratorValue1(String iteratorValue1) {
+ this.iteratorValue1 = iteratorValue1;
+ }
+
+
+
+ public String getIteratorValue2() {
+ return iteratorValue2;
+ }
+ public void setIteratorValue2(String iteratorValue2) {
+ this.iteratorValue2 = iteratorValue2;
+ }
+
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml
new file mode 100644
index 000000000..55f9577b2
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ true
+ Value must not be empty
+
+
+
+
+
+
+ Count must be an integer
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo.java
new file mode 100644
index 000000000..bbd214ae5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.tag.nonui.iteratortag;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public class IteratorGeneratorTagDemo extends ActionSupport {
+
+ private static final long serialVersionUID = 6893616642389337039L;
+
+ private String value;
+ private Integer count;
+ private String separator;
+
+
+ public String getValue() {
+ return value;
+ }
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+
+ public Integer getCount() {
+ return count;
+ }
+ public void setCount(Integer count) {
+ this.count = count;
+ }
+
+
+
+ public String getSeparator() {
+ return this.separator;
+ }
+ public void setSeparator(String separator) {
+ this.separator = separator;
+ }
+
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/MergeIteratorTagDemo.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/MergeIteratorTagDemo.java
new file mode 100644
index 000000000..9bd13c43d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/MergeIteratorTagDemo.java
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.tag.nonui.iteratortag;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.Validateable;
+
+
+/**
+ */
+public class MergeIteratorTagDemo extends ActionSupport implements Validateable {
+
+ private static final long serialVersionUID = 4401107963952961695L;
+
+ private String iteratorValue1;
+ private String iteratorValue2;
+
+
+ public void validate() {
+ if (iteratorValue1 == null || iteratorValue1.trim().length() <= 0 ) {
+ addFieldError("iteratorValue1", "iterator value 1 cannot be empty");
+ }
+ else if (iteratorValue1.trim().indexOf(",") <= 0) {
+ addFieldError("iteratorValue1", "iterator value 1 needs to be comma separated");
+ }
+ if (iteratorValue2 == null || iteratorValue2.trim().length() <= 0) {
+ addFieldError("iteratorValue2", "iterator value 2 cannot be empty");
+ }
+ else if (iteratorValue2.trim().indexOf(",") <= 0) {
+ addFieldError("iteratorValue2", "iterator value 2 needs to be comma separated");
+ }
+ }
+
+
+
+ public String getIteratorValue1() {
+ return this.iteratorValue1;
+ }
+ public void setIteratorValue1(String iteratorValue1) {
+ this.iteratorValue1 = iteratorValue1;
+ }
+
+
+
+ public String getIteratorValue2() {
+ return this.iteratorValue2;
+ }
+ public void setIteratorValue2(String iteratorValue2) {
+ this.iteratorValue2 = iteratorValue2;
+ }
+
+
+
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/SubsetIteratorTagDemo.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/SubsetIteratorTagDemo.java
new file mode 100644
index 000000000..c313eb7ed
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tag/nonui/iteratortag/SubsetIteratorTagDemo.java
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.tag.nonui.iteratortag;
+
+import com.opensymphony.xwork2.ActionSupport;
+import com.opensymphony.xwork2.Validateable;
+
+/**
+ *
+ */
+public class SubsetIteratorTagDemo extends ActionSupport implements Validateable {
+
+ private static final long serialVersionUID = -8151855954644052650L;
+
+ private String iteratorValue;
+ private Integer count;
+ private Integer start;
+
+
+ public void validate() {
+ if (iteratorValue == null || iteratorValue.trim().length() <= 0 ) {
+ addFieldError("iteratorValue1", "iterator value 1 cannot be empty");
+ }
+ else if (iteratorValue.trim().indexOf(",") <= 0) {
+ addFieldError("iteratorValue1", "iterator value 1 needs to be comma separated");
+ }
+ }
+
+
+
+ public String getIteratorValue() {
+ return this.iteratorValue;
+ }
+ public void setIteratorValue(String iteratorValue) {
+ this.iteratorValue = iteratorValue;
+ }
+
+
+
+ public Integer getCount() {
+ return this.count;
+ }
+ public void setCount(Integer count) {
+ this.count = count;
+ }
+
+
+
+ public Integer getStart() {
+ return this.start;
+ }
+ public void setStart(Integer start) {
+ this.start = start;
+ }
+
+
+
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+
+
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/token/TokenAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/token/TokenAction.java
new file mode 100644
index 000000000..9101dd40d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/token/TokenAction.java
@@ -0,0 +1,81 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.token;
+
+import com.opensymphony.xwork2.ActionContext;
+import com.opensymphony.xwork2.ActionSupport;
+
+import java.util.Date;
+
+/**
+ * Example to illustrate the token and token-session interceptor.
+ *
+ */
+public class TokenAction extends ActionSupport {
+
+ private static final long serialVersionUID = 616150375751184884L;
+
+ private int amount;
+
+ public String execute() throws Exception {
+ // transfer from source to destination
+
+ Integer balSource = (Integer) ActionContext.getContext().getSession().get("balanceSource");
+ Integer balDest = (Integer) ActionContext.getContext().getSession().get("balanceDestination");
+
+ Integer newSource = new Integer(balSource.intValue() - amount);
+ Integer newDest = new Integer(balDest.intValue() + amount);
+
+ ActionContext.getContext().getSession().put("balanceSource", newSource);
+ ActionContext.getContext().getSession().put("balanceDestination", newDest);
+ ActionContext.getContext().getSession().put("time", new Date());
+
+ Thread.sleep(2000); // to simulate processing time
+
+ return SUCCESS;
+ }
+
+ public String doInput() throws Exception {
+ // prepare input form
+ Integer balSource = (Integer) ActionContext.getContext().getSession().get("balanceSource");
+ Integer balDest = (Integer) ActionContext.getContext().getSession().get("balanceDestination");
+
+ if (balSource == null) {
+ // first time set up an initial account balance
+ balSource = new Integer(1200);
+ ActionContext.getContext().getSession().put("balanceSource", balSource);
+ }
+
+ if (balDest == null) {
+ // first time set up an initial account balance
+ balDest = new Integer(2500);
+ ActionContext.getContext().getSession().put("balanceDestination", balDest);
+ }
+
+ return INPUT;
+ }
+
+ public int getAmount() {
+ return amount;
+ }
+
+ public void setAmount(int amount) {
+ this.amount = amount;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName.java
new file mode 100644
index 000000000..4fa481726
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName.java
@@ -0,0 +1,23 @@
+package org.apache.struts2.showcase.tutorial;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+public class HelloName extends ActionSupport {
+
+ public String execute() throws Exception {
+ if (getName() == null || getName().length() == 0)
+ return ERROR;
+ else
+ return SUCCESS;
+ }
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName2.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName2.java
new file mode 100644
index 000000000..11d51a570
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloName2.java
@@ -0,0 +1,29 @@
+package org.apache.struts2.showcase.tutorial;
+
+import com.opensymphony.xwork2.ActionSupport;
+import org.apache.struts2.interceptor.ParameterAware;
+
+import java.util.Map;
+
+public class HelloName2 extends ActionSupport implements ParameterAware {
+
+ public static String NAME = "name";
+
+ public String execute() {
+ String[] name = (String[]) parameters.get(NAME);
+ if (name == null || name[0] == null || name[0].length() == 0)
+ return ERROR;
+ else
+ return SUCCESS;
+ }
+
+ Map parameters;
+
+ public Map getParameters() {
+ return parameters;
+ }
+
+ public void setParameters(Map parameters) {
+ this.parameters = parameters;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloWorld.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloWorld.java
new file mode 100644
index 000000000..28a45ba76
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/tutorial/HelloWorld.java
@@ -0,0 +1,23 @@
+package org.apache.struts2.showcase.tutorial;
+
+import com.opensymphony.xwork2.Action;
+
+import java.text.DateFormat;
+import java.util.Date;
+
+public class HelloWorld implements Action {
+
+ public String execute() {
+ message = "Hello, World!\n";
+ message += "The time is:\n";
+ message += DateFormat.getDateInstance().format(new Date());
+ return SUCCESS;
+ }
+
+ private String message;
+
+ public String getMessage() {
+ return message;
+ }
+
+}
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AbstractValidationActionSupport.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AbstractValidationActionSupport.java
new file mode 100644
index 000000000..39d1047f8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/AbstractValidationActionSupport.java
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+public abstract class AbstractValidationActionSupport extends ActionSupport {
+
+ public String submit() throws Exception {
+ return "success";
+ }
+
+ public String input() throws Exception {
+ return "input";
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties
new file mode 100644
index 000000000..2f970dc18
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties
@@ -0,0 +1 @@
+dateValidatorField=java.util.Date
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml
new file mode 100644
index 000000000..215a7c9ac
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ true
+
+
+
+
+
+ 1
+ 10
+
+
+
+
+
+ 01/01/1990
+ 01/01/2000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+ 2
+ true
+
+
+
+
+
+ .*\.txt
+
+
+
+
+
+ (fieldExpressionValidatorField == requiredValidatorField)
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml
new file mode 100644
index 000000000..97250cf93
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 1
+ 10
+
+
+
+
+
+ 01/01/1990
+ 01/01/2000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+ 2
+ true
+
+
+
+
+
+ .*\.txt
+
+
+
+
+
+ (fieldExpressionValidatorField == requiredValidatorField)
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.java
new file mode 100644
index 000000000..9da8bd8af
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.java
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+import java.sql.Date;
+
+/**
+ */
+
+// START SNIPPET: fieldValidatorsExample
+
+public class FieldValidatorsExampleAction extends AbstractValidationActionSupport {
+
+ private static final long serialVersionUID = -4829381083003175423L;
+
+ private String requiredValidatorField = null;
+ private String requiredStringValidatorField = null;
+ private Integer integerValidatorField = null;
+ private Date dateValidatorField = null;
+ private String emailValidatorField = null;
+ private String urlValidatorField = null;
+ private String stringLengthValidatorField = null;
+ private String regexValidatorField = null;
+ private String fieldExpressionValidatorField = null;
+
+
+
+ public Date getDateValidatorField() {
+ return dateValidatorField;
+ }
+ public void setDateValidatorField(Date dateValidatorField) {
+ this.dateValidatorField = dateValidatorField;
+ }
+ public String getEmailValidatorField() {
+ return emailValidatorField;
+ }
+ public void setEmailValidatorField(String emailValidatorField) {
+ this.emailValidatorField = emailValidatorField;
+ }
+ public Integer getIntegerValidatorField() {
+ return integerValidatorField;
+ }
+ public void setIntegerValidatorField(Integer integerValidatorField) {
+ this.integerValidatorField = integerValidatorField;
+ }
+ public String getRegexValidatorField() {
+ return regexValidatorField;
+ }
+ public void setRegexValidatorField(String regexValidatorField) {
+ this.regexValidatorField = regexValidatorField;
+ }
+ public String getRequiredStringValidatorField() {
+ return requiredStringValidatorField;
+ }
+ public void setRequiredStringValidatorField(String requiredStringValidatorField) {
+ this.requiredStringValidatorField = requiredStringValidatorField;
+ }
+ public String getRequiredValidatorField() {
+ return requiredValidatorField;
+ }
+ public void setRequiredValidatorField(String requiredValidatorField) {
+ this.requiredValidatorField = requiredValidatorField;
+ }
+ public String getStringLengthValidatorField() {
+ return stringLengthValidatorField;
+ }
+ public void setStringLengthValidatorField(String stringLengthValidatorField) {
+ this.stringLengthValidatorField = stringLengthValidatorField;
+ }
+ public String getFieldExpressionValidatorField() {
+ return fieldExpressionValidatorField;
+ }
+ public void setFieldExpressionValidatorField(
+ String fieldExpressionValidatorField) {
+ this.fieldExpressionValidatorField = fieldExpressionValidatorField;
+ }
+
+ public String getUrlValidatorField() {
+ return urlValidatorField;
+ }
+
+ public void setUrlValidatorField(String urlValidatorField) {
+ this.urlValidatorField = urlValidatorField;
+ }
+}
+
+
+// END SNIPPET: fieldValidatorsExample
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties
new file mode 100644
index 000000000..14f04121a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties
@@ -0,0 +1 @@
+i18n.requiredstring=Test String for required Strings...
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml
new file mode 100644
index 000000000..cba25b09e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction.java
new file mode 100644
index 000000000..1461fcda0
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+/**
+ */
+
+// START SNIPPET: nonFieldValidatorsExample
+
+public class NonFieldValidatorsExampleAction extends AbstractValidationActionSupport {
+
+ private static final long serialVersionUID = -524460368233581186L;
+
+ private String someText;
+ private String someTextRetype;
+ private String someTextRetypeAgain;
+
+ public String getSomeText() {
+ return someText;
+ }
+ public void setSomeText(String someText) {
+ this.someText = someText;
+ }
+ public String getSomeTextRetype() {
+ return someTextRetype;
+ }
+ public void setSomeTextRetype(String someTextRetype) {
+ this.someTextRetype = someTextRetype;
+ }
+ public String getSomeTextRetypeAgain() {
+ return someTextRetypeAgain;
+ }
+ public void setSomeTextRetypeAgain(String someTextRetypeAgain) {
+ this.someTextRetypeAgain = someTextRetypeAgain;
+ }
+}
+
+
+// END SNIPPET: nonFieldValidatorsExample
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction-validation.xml
new file mode 100644
index 000000000..dd716fade
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction-validation.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ You must enter a name
+
+
+
+
+ 13
+ 19
+ Only people ages 13 to 19 may take this quiz
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction.java
new file mode 100644
index 000000000..b1c4e6b6f
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/QuizAction.java
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ */
+
+// START SNIPPET: quizAction
+
+public class QuizAction extends ActionSupport {
+
+ private static final long serialVersionUID = -7505437345373234225L;
+
+ String name;
+ int age;
+ String answer;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public int getAge() {
+ return age;
+ }
+
+ public void setAge(int age) {
+ this.age = age;
+ }
+
+ public String getAnswer() {
+ return answer;
+ }
+
+ public void setAnswer(String answer) {
+ this.answer = answer;
+ }
+}
+
+// END SNIPPET: quizAction
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/SubmitApplication.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/SubmitApplication.java
new file mode 100644
index 000000000..7fbfecac2
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/SubmitApplication.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ * @version $Date$ $Id$
+ */
+public class SubmitApplication extends ActionSupport {
+
+ private String name;
+ private Integer age;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+ public String getName() {
+ return this.name;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+ public Integer getAge() {
+ return age;
+ }
+
+ public String submitApplication() throws Exception {
+ return SUCCESS;
+ }
+
+ public String applicationOk() throws Exception {
+ addActionMessage("Your application looks ok.");
+ return SUCCESS;
+ }
+ public String cancelApplication() throws Exception {
+ addActionMessage("So you have decided to cancel the application");
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User-userContext-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User-userContext-validation.xml
new file mode 100644
index 000000000..508eb6590
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User-userContext-validation.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ Name Required
+
+
+
+
+ 1
+ 100
+ Age Required (1-100)
+
+
+
+
+ Birthday Required
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User.java
new file mode 100644
index 000000000..32a88f228
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/User.java
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+import java.sql.Date;
+
+/**
+ */
+public class User {
+
+ private String name;
+ private Integer age;
+ private Date birthday;
+
+
+ public Integer getAge() {
+ return age;
+ }
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+ public Date getBirthday() {
+ return birthday;
+ }
+ public void setBirthday(Date birthday) {
+ this.birthday = birthday;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+}
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml
new file mode 100644
index 000000000..a8af8f005
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+ userContext
+ true
+ User:
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction.java
new file mode 100644
index 000000000..08a489d19
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.validation;
+
+
+// START SNIPPET: visitorValidatorsExample
+
+public class VisitorValidatorsExampleAction extends AbstractValidationActionSupport {
+
+ private static final long serialVersionUID = 4375454086939598216L;
+
+ private User user;
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User user) {
+ this.user = user;
+ }
+}
+
+
+// END SNIPPET: visitorValidatorsExample
diff --git a/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/wait/LongProcessAction.java b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/wait/LongProcessAction.java
new file mode 100644
index 000000000..7f33be892
--- /dev/null
+++ b/trunk/apps/showcase/src/main/java/org/apache/struts2/showcase/wait/LongProcessAction.java
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.wait;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * Example to illustrate the execAndWait interceptor.
+ *
+ */
+public class LongProcessAction extends ActionSupport {
+
+ private static final long serialVersionUID = 2471910747833998708L;
+
+ private int time;
+
+ public int getTime() {
+ return time;
+ }
+
+ public void setTime(int time) {
+ this.time = time;
+ }
+
+ public String execute() throws Exception {
+ System.err.println("time: " + time);
+ Thread.sleep(time);
+
+ return SUCCESS;
+ }
+
+}
diff --git a/trunk/apps/showcase/src/main/resources/globalMessages.properties b/trunk/apps/showcase/src/main/resources/globalMessages.properties
new file mode 100644
index 000000000..24a39d45c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/globalMessages.properties
@@ -0,0 +1,7 @@
+save=Save
+
+item.edit=Edit {0}
+item.create=Create {0}
+item.list={0} List
+
+token.transfer.time=The bank transfer was executed at {0,date,HH:mm:ss MM-dd-yyyy}
diff --git a/trunk/apps/showcase/src/main/resources/globalMessages_de.properties b/trunk/apps/showcase/src/main/resources/globalMessages_de.properties
new file mode 100644
index 000000000..0dc66efa8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/globalMessages_de.properties
@@ -0,0 +1,7 @@
+save=Speichern
+
+item.edit={0} bearbeiten
+item.create={0} neu anlegen
+item.list={0}-Liste
+
+token.transfer.time=Die \u00dcberweisung wurde am {0,date,HH:mm:ss MM-dd-yyyy} durchgef\u00fchrt
diff --git a/trunk/apps/showcase/src/main/resources/log4j.properties b/trunk/apps/showcase/src/main/resources/log4j.properties
new file mode 100644
index 000000000..226f3de08
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/log4j.properties
@@ -0,0 +1,31 @@
+#
+# Log4J Settings for log4j 1.2.x (via jakarta-commons-logging)
+#
+# The five logging levels used by Log are (in order):
+#
+# 1. DEBUG (the least serious)
+# 2. INFO
+# 3. WARN
+# 4. ERROR
+# 5. FATAL (the most serious)
+
+
+# Set root logger level to WARN and append to stdout
+log4j.rootLogger=WARN, stdout
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+
+# Pattern to output the caller's file name and line number.
+log4j.appender.stdout.layout.ConversionPattern=%d %5p (%c:%L) - %m%n
+
+# Print only messages of level ERROR or above in the package noModule.
+log4j.logger.noModule=FATAL
+
+# OpenSymphony Stuff
+log4j.logger.com.opensymphony=INFO
+log4j.logger.org.apache.struts2=DEBUG
+
+# Spring Stuff
+log4j.logger.org.springframework=INFO
+
diff --git a/trunk/apps/showcase/src/main/resources/myTemplateDir/myTheme/myAnotherTemplate.ftl b/trunk/apps/showcase/src/main/resources/myTemplateDir/myTheme/myAnotherTemplate.ftl
new file mode 100644
index 000000000..544f44e60
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/myTemplateDir/myTheme/myAnotherTemplate.ftl
@@ -0,0 +1,6 @@
+
+
+Freemarker Custom Template -
+parameter 'paramName' - ${parameters.paramName}
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/DateAction.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/DateAction.properties
new file mode 100644
index 000000000..d49c743a5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/DateAction.properties
@@ -0,0 +1 @@
+struts.date.format=yyyy/MM/dd hh:mm:ss
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml
new file mode 100644
index 000000000..8bf17c7c1
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/LotsOfRichtexteditorAction-lotsOfRichtexteditorSubmit-validation.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+ Description1 Is Required !!!
+
+
+
+
+
+ Description2 Is Required !!!
+
+
+
+
+
+ Description3 Is Required !!!
+
+
+
+
+
+ Description4 Is Required !!!
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/UITagExample-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/UITagExample-conversion.properties
new file mode 100644
index 000000000..2415dcf3c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/UITagExample-conversion.properties
@@ -0,0 +1 @@
+Element_friends = java.lang.String
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties
new file mode 100644
index 000000000..21d3eda97
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-conversion.properties
@@ -0,0 +1 @@
+Element_selectedSkills=java.lang.String
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-validation.xml
new file mode 100644
index 000000000..c49959888
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction-validation.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction.properties
new file mode 100644
index 000000000..e2e548b3c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction.properties
@@ -0,0 +1,9 @@
+employee=Employee
+employee.firstName=First Name
+employee.lastName=Last Name
+employee.description=Description
+
+employee.id.required=Id is required
+employee.lastName.required=Last Name is required
+employee.birthDate.required=Birthdate is required
+employee.backtolist=Back to Employee List
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction_de.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction_de.properties
new file mode 100644
index 000000000..ca594de4d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/EmployeeAction_de.properties
@@ -0,0 +1,9 @@
+employee=Mitarbeiter
+employee.firstName=Vorname
+employee.lastName=Nachname
+employee.description=Beschreibung
+
+employee.id.required=ID muß angegeben werden
+employee.lastName.required=Nachname wird benötigt
+employee.birthDate.required=Geburtsdatum wird benötigt
+employee.backtolist=Zurück zur Mitarbeiterliste
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction-validation.xml
new file mode 100644
index 000000000..486e79f61
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction-validation.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+ true
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction.properties
new file mode 100644
index 000000000..27b7c81df
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction.properties
@@ -0,0 +1,6 @@
+skill=Skill
+skill.name=Name
+skill.description=Description
+
+skill.name.required=Name is required
+skill.backtolist=Back to Skill List
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction_de.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction_de.properties
new file mode 100644
index 000000000..7c7156f71
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/action/SkillAction_de.properties
@@ -0,0 +1,6 @@
+skill=Kenntnis
+skill.name=Name
+skill.description=Beschreibung
+
+skill.name.required=Name muss angegeben werden
+skill.backtolist=Zurück zur Kenntnis Liste
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/ajax/Example5Action-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/ajax/Example5Action-validation.xml
new file mode 100644
index 000000000..b80e7d54a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/ajax/Example5Action-validation.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ Name is required
+
+
+
+
+ Age is required
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatLoginAction-chatLogin-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatLoginAction-chatLogin-validation.xml
new file mode 100644
index 000000000..d4ab29906
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatLoginAction-chatLogin-validation.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ true
+ Name is required
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatMessage-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatMessage-conversion.properties
new file mode 100644
index 000000000..8869d38e6
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/ChatMessage-conversion.properties
@@ -0,0 +1 @@
+creationDate=org.apache.struts2.showcase.chat.DateConverter
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/CrudRoomAction-createRoom-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/CrudRoomAction-createRoom-validation.xml
new file mode 100644
index 000000000..bf8977c3b
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/CrudRoomAction-createRoom-validation.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+ true
+ Room name is required
+
+
+
+
+ true
+ Room description is required
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/Room-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/Room-conversion.properties
new file mode 100644
index 000000000..8869d38e6
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/Room-conversion.properties
@@ -0,0 +1 @@
+creationDate=org.apache.struts2.showcase.chat.DateConverter
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/SendMessageToRoomAction-sendMessageToRoom-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/SendMessageToRoomAction-sendMessageToRoom-validation.xml
new file mode 100644
index 000000000..b4197a443
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/chat/SendMessageToRoomAction-sendMessageToRoom-validation.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+ true
+ Message is required
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties
new file mode 100644
index 000000000..12f602f16
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/conversion/PersonAction-conversion.properties
@@ -0,0 +1 @@
+Element_persons=org.apache.struts2.showcase.conversion.Person
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/CreatePerson-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/CreatePerson-validation.xml
new file mode 100644
index 000000000..6d19ebdf6
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/CreatePerson-validation.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/EditPerson-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/EditPerson-conversion.properties
new file mode 100644
index 000000000..00b2a0365
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/EditPerson-conversion.properties
@@ -0,0 +1,3 @@
+KeyProperty_persons=id
+Element_persons=org.apache.struts2.showcase.person.Person
+CreateIfNull_persons=true
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/Person-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/Person-validation.xml
new file mode 100644
index 000000000..da2c81f0c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/person/Person-validation.xml
@@ -0,0 +1,13 @@
+
+
+
+
+ You must enter a first name.
+
+
+
+
+ You must enter a last name
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml
new file mode 100644
index 000000000..55f9577b2
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/tag/nonui/iteratortag/IteratorGeneratorTagDemo-validation.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ true
+ Value must not be empty
+
+
+
+
+
+
+ Count must be an integer
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties
new file mode 100644
index 000000000..2f970dc18
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-conversion.properties
@@ -0,0 +1 @@
+dateValidatorField=java.util.Date
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml
new file mode 100644
index 000000000..215a7c9ac
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitClientSideValidationExample-validation.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ true
+
+
+
+
+
+ 1
+ 10
+
+
+
+
+
+ 01/01/1990
+ 01/01/2000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+ 2
+ true
+
+
+
+
+
+ .*\.txt
+
+
+
+
+
+ (fieldExpressionValidatorField == requiredValidatorField)
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml
new file mode 100644
index 000000000..97250cf93
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction-submitFieldValidatorsExamples-validation.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ 1
+ 10
+
+
+
+
+
+ 01/01/1990
+ 01/01/2000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4
+ 2
+ true
+
+
+
+
+
+ .*\.txt
+
+
+
+
+
+ (fieldExpressionValidatorField == requiredValidatorField)
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties
new file mode 100644
index 000000000..14f04121a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/FieldValidatorsExampleAction.properties
@@ -0,0 +1 @@
+i18n.requiredstring=Test String for required Strings...
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml
new file mode 100644
index 000000000..cba25b09e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/NonFieldValidatorsExampleAction-submitNonFieldValidatorsExamples-validation.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/QuizAction-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/QuizAction-validation.xml
new file mode 100644
index 000000000..dd716fade
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/QuizAction-validation.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ You must enter a name
+
+
+
+
+ 13
+ 19
+ Only people ages 13 to 19 may take this quiz
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/SubmitApplication-submitApplication-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/SubmitApplication-submitApplication-validation.xml
new file mode 100644
index 000000000..0dbb123f9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/SubmitApplication-submitApplication-validation.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ You must provide a name
+
+
+
+
+ You must provide your age
+
+
+ 18
+ 50
+ Your age must be between 18 and 50
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/User-userContext-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/User-userContext-validation.xml
new file mode 100644
index 000000000..508eb6590
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/User-userContext-validation.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ Name Required
+
+
+
+
+ 1
+ 100
+ Age Required (1-100)
+
+
+
+
+ Birthday Required
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml
new file mode 100644
index 000000000..a8af8f005
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/org/apache/struts2/showcase/validation/VisitorValidatorsExampleAction-submitVisitorValidatorsExamples-validation.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+ userContext
+ true
+ User:
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-actionchaining.xml b/trunk/apps/showcase/src/main/resources/struts-actionchaining.xml
new file mode 100644
index 000000000..f0818a0b4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-actionchaining.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+ actionChain2
+
+
+ actionChain3
+
+
+ /actionchaining/actionChainingResult.jsp
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-ajax.xml b/trunk/apps/showcase/src/main/resources/struts-ajax.xml
new file mode 100644
index 000000000..5cbc9512c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-ajax.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+ /ajax/AjaxResult.jsp
+
+
+
+ /ajax/AjaxResult2.js
+
+
+
+ /ajax/AjaxResult3.jsp
+
+
+
+ /ajax/remoteforms/test2.jsp
+
+
+
+ /ajax/remoteforms/test3.jsp
+
+
+
+ /ajax/testjs.jsp
+
+
+
+ /ajax/tree/tree.jsp
+
+
+
+ /ajax/tree/getCategory.jsp
+
+
+
+ /ajax/tree/toggle.jsp
+
+
+
+ /ajax/tabbedpanel/example4.ftl
+
+
+
+ /ajax/tabbedpanel/example5.jsp
+ /ajax/tabbedpanel/example5Ok.jsp
+
+
+
+
+
+
+ /ajax/tabbedpanel/nodecorate/panel1.ftl
+
+
+ /ajax/tabbedpanel/nodecorate/panel2.ftl
+
+
+ /ajax/tabbedpanel/nodecorate/panel3.ftl
+
+
+ /ajax/tabbedpanel/nodecorate/panel2Submit.ftl
+
+
+ /ajax/tabbedpanel/nodecorate/panel3Submit.ftl
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-chat.xml b/trunk/apps/showcase/src/main/resources/struts-chat.xml
new file mode 100644
index 000000000..173d3bcee
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-chat.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ input,back,cancel,browse
+
+
+ input,back,cancel,browse
+
+
+
+
+
+
+ /chat/chatLogin.ftl
+
+
+
+
+ /chat/roomSelection.ftl
+
+
+
+
+ /chat/showRooms.action
+ /chat/chatLogin.ftl
+
+
+
+
+ /chat/main.action
+
+
+
+
+ /chat/roomSelection.ftl
+
+
+
+
+ /chat/showRoom.ftl
+
+
+
+
+ /chat/showRooms.action
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ input,back,cancel,browse
+
+
+ input,back,cancel,browse
+
+
+
+
+
+
+
+
+ /chat/usersAvailable.ftl
+
+
+
+
+ /chat/roomsAvailable.ftl
+
+
+
+
+ /chat/createRoom.ftl
+ /chat/createRoom.ftl
+
+
+
+
+ /chat/messagesAvailableInRoom.ftl
+ /chat/messagesAvailableInRoom.ftl
+
+
+
+
+ /chat/sendMessageToRoomResult.ftl
+ /chat/sendMessageToRoomResult.ftl
+
+
+
+
+ /chat/usersAvailableInRoom.ftl
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-continuations.xml b/trunk/apps/showcase/src/main/resources/struts-continuations.xml
new file mode 100644
index 000000000..dc806e3f8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-continuations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+ guess.ftl
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-conversion.xml b/trunk/apps/showcase/src/main/resources/struts-conversion.xml
new file mode 100644
index 000000000..c3259e6a9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-conversion.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+ enterPersonInfo.jsp
+
+
+ showPersonInfo.jsp
+ enterPersonInfo.jsp
+
+
+ /conversion/enterPersonInfo.jsp
+
+
+ /conversion/PersonAction.java.txt
+
+
+ /conversion/Person.java.txt
+
+
+
+
+
+ enterAddressInfo.jsp
+
+
+ showAddressInfo.jsp
+ enterAddressInfo.jsp
+
+
+ /conversion/enterAddressInfo.jsp
+
+
+ /conversion/AddressAction.java.txt
+
+
+ /conversion/Address.java.txt
+
+
+
+
+
+ enterOperations.jsp
+
+
+ showOperations.jsp
+ enterOperations.jsp
+
+
+ /conversion/enterOperations.jsp
+
+
+ /conversion/OperationsEnum.java.txt
+
+
+ /conversion/OperationsEnumAction.java.txt
+
+
+ /conversion/EnumTypeConverter.java.txt
+
+
+ /conversion/OperationsEnumActionConversion.txt
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-filedownload.xml b/trunk/apps/showcase/src/main/resources/struts-filedownload.xml
new file mode 100644
index 000000000..c64a643ce
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-filedownload.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+ image/jpeg
+ imageStream
+ filename="logo.png"
+ 4096
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-fileupload.xml b/trunk/apps/showcase/src/main/resources/struts-fileupload.xml
new file mode 100644
index 000000000..b416fac2e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-fileupload.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+ upload.jsp
+
+
+
+ upload-success.jsp
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-freemarker.xml b/trunk/apps/showcase/src/main/resources/struts-freemarker.xml
new file mode 100644
index 000000000..af352a4ca
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-freemarker.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+ /freemarker/customFreemarkerManagerUsage.ftl
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-hangman.xml b/trunk/apps/showcase/src/main/resources/struts-hangman.xml
new file mode 100644
index 000000000..b12ddcee4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-hangman.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+ /hangman/hangmanMenu.ftl
+
+
+ /hangman/hangmanAjax.ftl
+
+
+ /hangman/hangmanNonAjax.ftl
+
+
+ /hangman/test.ftl
+
+
+ /hangman/blank.ftl
+
+
+ /hangman/hangmanNonAjax.ftl
+
+
+
+
+
+
+
+ /hangman/blank.ftl
+
+
+ /hangman/updateVocabCharacters.ftl
+
+
+ /hangman/updateCharacterAvailable.ftl
+
+
+ /hangman/updateScaffold.ftl
+
+
+ /hangman/updateGuessLeft.ftl
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-integration.xml b/trunk/apps/showcase/src/main/resources/struts-integration.xml
new file mode 100644
index 000000000..66f28d2d7
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-integration.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+ org.apache.struts2.showcase.integration.GangsterForm
+ gangsterForm
+
+
+ /org/apache/struts/validator/validator-rules.xml,/WEB-INF/validation.xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.struts2.showcase.integration.EditGangsterAction
+ modelDriven.jsp
+
+
+
+
+ org.apache.struts2.showcase.integration.SaveGangsterAction
+ true
+ modelDriven.jsp
+ modelDrivenResult.jsp
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/resources/struts-jsf.xml b/trunk/apps/showcase/src/main/resources/struts-jsf.xml
new file mode 100644
index 000000000..2ef59b500
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-jsf.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ list.action
+ list.action
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-model-driven.xml b/trunk/apps/showcase/src/main/resources/struts-model-driven.xml
new file mode 100644
index 000000000..bf3d57e4e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-model-driven.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+ modelDriven.jsp
+
+
+
+
+ modelDrivenResult.jsp
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/resources/struts-person.xml b/trunk/apps/showcase/src/main/resources/struts-person.xml
new file mode 100644
index 000000000..88462257d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-person.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+ listPeople.ftl
+
+
+
+ listPeople.action
+ newPerson.ftl
+
+
+
+ editPeople.jsp
+
+
+
+ editPeople.jsp
+ listPeople.action
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-tags-non-ui.xml b/trunk/apps/showcase/src/main/resources/struts-tags-non-ui.xml
new file mode 100644
index 000000000..0200b7b8f
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-tags-non-ui.xml
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+ /tags/non-ui/actionTag/showActionTagDemo.jsp
+
+
+ /tags/non-ui/actionTag/includedPage.jsp
+
+
+ /tags/non-ui/actionTag/includedPage2.jsp
+
+
+ /tags/non-ui/actionTag/includedPage3.jsp
+
+
+ /tags/non-ui/actionTag/showActionTagDemo.jsp
+
+
+
+
+
+
+
+
+
+ /tags/non-ui/iteratorTag/showIteratorGeneratorTagDemo.jsp
+
+
+ /tags/non-ui/iteratorTag/showIteratorGeneratorTagDemo.jsp
+ /tags/non-ui/iteratorTag/iteratorGeneratorTagDemoResult.jsp
+
+
+
+
+
+
+
+
+
+ /tags/non-ui/iteratorTag/showAppendIteratorTagDemo.jsp
+
+
+ /tag/non-ui/iteratorTag/showAppendIteratorTagDemo.jsp
+ /tags/non-ui/iteratorTag/appendIteratorTagDemoResult.jsp
+
+
+
+
+
+
+
+
+
+ /tags/non-ui/iteratorTag/showMergeIteratorTagDemo.jsp
+
+
+ /tags/non-ui/iteratorTag/showMergeIteratorTagDemo.jsp
+ /tags/non-ui/iteratorTag/mergeIteratorTagDemoResult.jsp
+
+
+
+
+
+
+
+
+ /tags/non-ui/iteratorTag/subsetIteratorTagDemo.jsp
+
+
+ /tags/non-ui/iteratorTag/subsetIteratorTagDemo.jsp
+ /tags/non-ui/iteratorTag/subsetIteratorTagDemoResult.jsp
+
+
+
+
+
+
+
+
+ /tags/non-ui/actionPrefix/actionPrefixExample.ftl
+
+
+ /tags/non-ui/actionPrefix/normalSubmit.ftl
+
+
+ /tags/non-ui/actionPrefix/methodPrefix.ftl
+
+
+ /tags/non-ui/actionPrefix/actionPrefix.ftl
+
+
+ /tags/non-ui/actionPrefix/redirectPrefix.ftl
+
+
+ /tags/non-ui/actionPrefix/redirectActionPrefix.ftl
+
+
+ /tags/non-ui/actionPrefix/actionPrefixExample.ftl
+
+
+
+
+
+
+
+
+ /tags/non-ui/ifTag/testIf.jsp
+
+
+ /tags/non-ui/ifTag/testIf.ftl
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-tags-ui.xml b/trunk/apps/showcase/src/main/resources/struts-tags-ui.xml
new file mode 100644
index 000000000..527470650
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-tags-ui.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+ example.jsp
+ example.jsp
+
+
+ exampleSubmited.jsp
+ example.jsp
+
+
+ example.vm
+ example.vm
+
+
+ exampleSubmited.vm
+ example.vm
+
+
+ lotsOfOptiontransferselect.jsp
+
+
+ lotsOfOptiontransferselect.jsp
+ lotsOfOptiontransferselectSubmit.jsp
+
+
+
+
+
+ /tags/ui/treeExampleDynamic.jsp
+
+
+
+
+
+
+ /tags/ui/componentTagExample.jsp
+
+
+
+
+
+
+
+
+
+ /tags/ui/staticTreeSelect.jsp
+
+
+ /tags/ui/dynamicTreeSelect.jsp
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-tags.xml b/trunk/apps/showcase/src/main/resources/struts-tags.xml
new file mode 100644
index 000000000..4b5995241
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-tags.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-token.xml b/trunk/apps/showcase/src/main/resources/struts-token.xml
new file mode 100644
index 000000000..a06098c37
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-token.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+ example1.jsp
+
+
+
+
+
+ doublePost.jsp
+ transferDone.jsp
+
+
+
+
+
+
+ example2.jsp
+
+
+
+
+
+ doublePost.jsp
+ transferDone.jsp
+
+
+
+
+
+
+ example3.jsp
+
+
+
+
+
+ doublePost.jsp
+ transferDone.jsp
+
+
+
+
+
+
+ example4.ftl
+
+
+
+
+
+ doublePost.jsp
+ transferDone.jsp
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-validation.xml b/trunk/apps/showcase/src/main/resources/struts-validation.xml
new file mode 100755
index 000000000..3cedcf4aa
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-validation.xml
@@ -0,0 +1,124 @@
+
+
+
+
+
+ quiz-basic.jsp
+ quiz-success.jsp
+
+
+
+ quiz-client.jsp
+ quiz-success.jsp
+
+
+
+ quiz-client-css.jsp
+ quiz-success.jsp
+
+
+
+ quiz-ajax.jsp
+ quiz-success.jsp
+
+
+
+
+
+
+
+ index.jsp
+
+
+
+
+
+
+
+
+ /validation/fieldValidatorsExample.jsp
+
+
+
+ /validation/fieldValidatorsExample.jsp
+ /validation/successFieldValidatorsExample.jsp
+
+
+
+
+
+
+
+
+
+ /validation/nonFieldValidatorsExample.jsp
+
+
+
+ /validation/nonFieldValidatorsExample.jsp
+ /validation/successNonFieldValidatorsExample.jsp
+
+
+
+
+
+
+
+
+
+ /validation/visitorValidatorsExample.jsp
+
+
+
+ /validation/visitorValidatorsExample.jsp
+ /validation/successVisitorValidatorsExample.jsp
+
+
+
+
+
+
+
+
+
+ /validation/clientSideValidationExample.jsp
+
+
+
+ /validation/clientSideValidationExample.jsp
+ /validation/successClientSideValidationExample.jsp
+
+
+
+
+
+
+
+
+ STORE
+
+
+ /validation/resubmitApplication.action
+ /validation/applicationOk.action
+
+
+
+ RETRIEVE
+
+ /validation/storeErrorsAcrossRequestExample.jsp
+
+
+
+ RETRIEVE
+
+ /validation/storeErrorsAcrossRequestOk.jsp
+
+
+ /validation/storeErrorsAcrossRequestCancel.jsp
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts-wait.xml b/trunk/apps/showcase/src/main/resources/struts-wait.xml
new file mode 100644
index 000000000..e39863416
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts-wait.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+ wait.jsp
+ complete.jsp
+
+
+
+
+
+ 2000
+
+ wait.jsp
+ complete.jsp
+
+
+
+
+
+ 3000
+ 1000
+
+ wait.jsp
+ complete.jsp
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/resources/struts.properties b/trunk/apps/showcase/src/main/resources/struts.properties
new file mode 100644
index 000000000..6352045a4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts.properties
@@ -0,0 +1,11 @@
+struts.i18n.reload=true
+struts.devMode = true
+struts.configuration.xml.reload=true
+struts.continuations.package = org.apache.struts2.showcase
+struts.objectFactory = spring
+struts.custom.i18n.resources=globalMessages
+#struts.action.extension=jspa
+struts.url.http.port = 8080
+struts.freemarker.manager.classname=customFreemarkerManager
+struts.serve.static=true
+struts.serve.static.browserCache=false
diff --git a/trunk/apps/showcase/src/main/resources/struts.xml b/trunk/apps/showcase/src/main/resources/struts.xml
new file mode 100644
index 000000000..2f316fa8d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/resources/struts.xml
@@ -0,0 +1,115 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ showcase.jsp
+
+
+
+ viewSource.jsp
+
+
+
+ /date.jsp
+
+
+
+
+
+
+
+
+ /empmanager/listSkills.jsp
+
+
+
+ /empmanager/editSkill.jsp
+
+
+
+
+ /empmanager/editSkill.jsp
+ edit.action?skillName=${currentSkill.name}
+
+
+ /empmanager/editSkill.jsp
+ edit.action?skillName=${currentSkill.name}
+
+
+
+
+
+
+
+ /empmanager/listEmployees.jsp
+
+
+
+ {1}
+ /empmanager/editEmployee.jsp
+ execute
+
+
+ /empmanager/editEmployee.jsp
+ edit-${currentEmployee.empId}.action
+
+
+ /empmanager/editEmployee.jsp
+ edit-${currentEmployee.empId}.action
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/applicationContext.xml b/trunk/apps/showcase/src/main/webapp/WEB-INF/applicationContext.xml
new file mode 100644
index 000000000..cec8c6871
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/applicationContext.xml
@@ -0,0 +1,117 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ A popular programming language that is used to create the Struts framework
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators.xml b/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators.xml
new file mode 100644
index 000000000..31936b952
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+ /debug.jsp
+ /styles/*
+ /scripts/*
+ /images/*
+ /dojo/*
+ /struts/*
+ /ajax/AjaxResult*
+ /AjaxTest.action
+ /ajax/remoteforms/AjaxRemoteForm.action
+ /tags/ui/ajax/*
+ /chat/ajax/*
+ /hangman/ajax/*
+ /nodecorate/*
+
+
+
+ /*
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp b/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
new file mode 100644
index 000000000..978b77380
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/decorators/main.jsp
@@ -0,0 +1,119 @@
+
+
+<%
+ response.setHeader("Pragma", "no-cache");
+ response.setHeader("Cache-Control", "no-cache");
+ response.setDateHeader("Expires", 0);
+
+ // Calculate the view sources url
+ String sourceUrl = request.getContextPath()+"/viewSource.action";
+ com.opensymphony.xwork2.ActionInvocation inv = com.opensymphony.xwork2.ActionContext.getContext().getActionInvocation();
+ org.apache.struts2.dispatcher.mapper.ActionMapping mapping = org.apache.struts2.ServletActionContext.getActionMapping();
+ if (inv != null) {
+ sourceUrl += "?config="+inv.getProxy().getConfig().getLocation().getURI()+":"+inv.getProxy().getConfig().getLocation().getLineNumber();
+ sourceUrl += "&className="+inv.getProxy().getConfig().getClassName();
+
+ if (inv.getResult() != null && inv.getResult() instanceof org.apache.struts2.dispatcher.StrutsResultSupport) {
+ sourceUrl += "&page="+mapping.getNamespace()+"/"+((org.apache.struts2.dispatcher.StrutsResultSupport)inv.getResult()).getLastFinalLocation();
+ }
+ } else {
+ sourceUrl += "?page="+request.getServletPath();
+ }
+%>
+<%@taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator" %>
+<%@taglib prefix="page" uri="http://www.opensymphony.com/sitemesh/page" %>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Navigation
+
+ ">Home
+ ">Config Browser
+ ">Continuations
+ ">Tags
+ ">File Upload
+ ">CRUD
+ ">Person Manager
+ ">Validation
+ ">AJAX
+ ">Action Chaining
+ ">Execute & Wait
+ ">Token
+ ">File Download
+ ">Conversion
+ ">JSF
+ ">Freemarker
+ ">Chat (AJAX)
+ ">Hangman
+ ">Help
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/dwr.xml b/trunk/apps/showcase/src/main/webapp/WEB-INF/dwr.xml
new file mode 100644
index 000000000..99869bf4a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/dwr.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ ]]>
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-decorator.tld b/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-decorator.tld
new file mode 100644
index 000000000..18f525c6e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-decorator.tld
@@ -0,0 +1,79 @@
+
+
+
+
+
+ 1.0
+ 1.1
+ SiteMesh Decorator Tags
+ sitemesh-decorator
+
+
+ head
+ com.opensymphony.module.sitemesh.taglib.decorator.HeadTag
+ JSP
+
+
+
+ body
+ com.opensymphony.module.sitemesh.taglib.decorator.BodyTag
+ JSP
+
+
+
+ title
+ com.opensymphony.module.sitemesh.taglib.decorator.TitleTag
+ JSP
+
+ default
+ false
+ true
+
+
+
+
+ getProperty
+ com.opensymphony.module.sitemesh.taglib.decorator.PropertyTag
+ JSP
+
+ property
+ true
+ true
+
+
+ default
+ false
+ true
+
+
+ writeEntireProperty
+ false
+ true
+
+
+
+
+ usePage
+ com.opensymphony.module.sitemesh.taglib.decorator.UsePageTag
+ com.opensymphony.module.sitemesh.taglib.decorator.UsePageTEI
+ JSP
+
+ id
+ true
+ false
+
+
+
+
+ useHtmlPage
+ com.opensymphony.module.sitemesh.taglib.decorator.UsePageTag
+ com.opensymphony.module.sitemesh.taglib.decorator.UseHTMLPageTEI
+ JSP
+
+ id
+ true
+ false
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-page.tld b/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-page.tld
new file mode 100644
index 000000000..797ec5d61
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh-page.tld
@@ -0,0 +1,95 @@
+
+
+
+
+
+ 1.0
+ 1.1
+ SiteMesh Page Tags
+ sitemesh-page
+
+
+ applyDecorator
+ com.opensymphony.module.sitemesh.taglib.page.ApplyDecoratorTag
+ JSP
+
+ name
+ false
+ true
+
+
+ page
+ false
+ true
+
+
+ title
+ false
+ true
+
+
+ id
+ false
+ true
+
+
+ contentType
+ false
+ true
+
+
+ encoding
+ false
+ true
+
+
+
+
+
+ apply-decorator
+ com.opensymphony.module.sitemesh.taglib.page.ApplyDecoratorTag
+ JSP
+
+ name
+ false
+ true
+
+
+ page
+ false
+ true
+
+
+ title
+ false
+ true
+
+
+ id
+ false
+ true
+
+
+ contentType
+ false
+ true
+
+
+ encoding
+ false
+ true
+
+
+
+
+ param
+ com.opensymphony.module.sitemesh.taglib.page.ParamTag
+ JSP
+
+ name
+ false
+ true
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh.xml b/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh.xml
new file mode 100644
index 000000000..cfd1b3449
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/sitemesh.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/validation.xml b/trunk/apps/showcase/src/main/webapp/WEB-INF/validation.xml
new file mode 100644
index 000000000..284975364
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/validation.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml b/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..6278bb6e8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,151 @@
+
+
+
+
+ Struts Showcase Application
+
+
+
+ struts-cleanup
+ org.apache.struts2.dispatcher.ActionContextCleanUp
+
+
+
+ struts
+ org.apache.struts2.dispatcher.FilterDispatcher
+
+
+
+ sitemesh
+ com.opensymphony.module.sitemesh.filter.PageFilter
+
+
+
+
+
+ struts-cleanup
+ /*
+
+
+
+ sitemesh
+ /*
+
+
+
+ struts
+ /*
+
+
+
+
+ org.springframework.web.context.ContextLoaderListener
+
+
+
+
+ org.apache.myfaces.webapp.StartupServletContextListener
+
+
+
+
+
+
+ org.apache.struts2.showcase.chat.ChatSessionListener
+
+
+
+
+
+
+ dwr
+ uk.ltd.getahead.dwr.DWRServlet
+
+ debug
+ true
+
+
+
+
+
+ faces
+ javax.faces.webapp.FacesServlet
+ 1
+
+
+
+
+ faces
+ *.action
+
+
+
+ dwr
+ /dwr/*
+
+
+
+
+
+
+
+
+
+ index.jsp
+ default.jsp
+ index.html
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/actionchaining/actionChainingResult.jsp b/trunk/apps/showcase/src/main/webapp/actionchaining/actionChainingResult.jsp
new file mode 100644
index 000000000..b16511308
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/actionchaining/actionChainingResult.jsp
@@ -0,0 +1,14 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Showcase - Action Chaining Result
+
+
+ Action Chaining Result:
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult.jsp b/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult.jsp
new file mode 100644
index 000000000..b93c00f92
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult.jsp
@@ -0,0 +1,10 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<%
+ request.setAttribute("decorator", "none");
+ response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
+ response.setHeader("Pragma","no-cache"); //HTTP 1.0
+ response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
+%>
+
+Result: @
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult2.js b/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult2.js
new file mode 100644
index 000000000..537c3905d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult2.js
@@ -0,0 +1,2 @@
+alert('This JavaScript currently being evaluated is the result...');
+alert('... of an action executed on the server!');
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult3.jsp b/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult3.jsp
new file mode 100644
index 000000000..45cb2b0ce
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/AjaxResult3.jsp
@@ -0,0 +1,12 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<%
+ request.setAttribute("decorator", "none");
+ response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
+ response.setHeader("Pragma","no-cache"); //HTTP 1.0
+ response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
+%>
+
+Result: @
+
+The value you entered was:
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/commonInclude.jsp b/trunk/apps/showcase/src/main/webapp/ajax/commonInclude.jsp
new file mode 100644
index 000000000..f004910a3
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/commonInclude.jsp
@@ -0,0 +1,4 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/footer.jsp b/trunk/apps/showcase/src/main/webapp/ajax/footer.jsp
new file mode 100644
index 000000000..482348732
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/footer.jsp
@@ -0,0 +1,9 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+
+
+Back To AJAX Examples
+Back To Showcase
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/index.jsp b/trunk/apps/showcase/src/main/webapp/ajax/index.jsp
new file mode 100644
index 000000000..75a5fce92
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/index.jsp
@@ -0,0 +1,20 @@
+
+AJAX Examples
+
+
+
+AJAX Example
+
+Note: these examples have only been tested under FireFox 1.5 and IE 6.
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example1.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example1.jsp
new file mode 100644
index 000000000..fe9b1d1e9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example1.jsp
@@ -0,0 +1,24 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+
+ Initial Content
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example2.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example2.jsp
new file mode 100644
index 000000000..9fbb89488
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example2.jsp
@@ -0,0 +1,24 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+ Initial Content
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example3.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example3.jsp
new file mode 100644
index 000000000..d90cb5178
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example3.jsp
@@ -0,0 +1,24 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+Initial Content
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example4.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example4.jsp
new file mode 100644
index 000000000..f8db61e46
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example4.jsp
@@ -0,0 +1,25 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+loading now
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example5.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example5.jsp
new file mode 100644
index 000000000..6fa03633e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example5.jsp
@@ -0,0 +1,24 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+loading now
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example6.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example6.jsp
new file mode 100644
index 000000000..3088742bc
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example6.jsp
@@ -0,0 +1,24 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+loading now
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example7.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example7.jsp
new file mode 100644
index 000000000..bff2bdfe7
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example7.jsp
@@ -0,0 +1,24 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+loading now
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example8.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example8.jsp
new file mode 100644
index 000000000..600027fcb
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/example8.jsp
@@ -0,0 +1,27 @@
+
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+
+ Initial Content ... should not change
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotediv/index.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/index.jsp
new file mode 100644
index 000000000..7bf1ec36c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotediv/index.jsp
@@ -0,0 +1,56 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ AJAX-based remote DIV tag
+ <%@ include file="/ajax/commonInclude.jsp" %>
+
+
+
+
+Examples
+
+
+
+
+ A simple DIV that refreshes only once
+
+
+
+ A simple DIV that updates every 2 seconds
+
+
+
+ A simple DIV that obtains the update freq (3 secs) from the value
+ stack/action
+
+
+
+ A simple DIV that updates every 5 seconds with loading text and reloading text
+
+
+
+ A simple DIV's that cannot contact the server
+
+
+
+ A simple DIV's that cannot contact the server and displays the transport error
+ message
+
+
+
+ A div that calls the server, and JS in the resulting page is executed
+
+
+
+ A div that will not update itself (updateFreq=0 and delay=0)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/index.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/index.jsp
new file mode 100644
index 000000000..9b96d0f10
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/index.jsp
@@ -0,0 +1,111 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+
+
+
+
+Remote form replacing another div:
+
+initial content
+
+
+
+
+
+
+
+
+
+Remote form replacing the forms content:
+
+
+
+
+
+
+
+
+Remote form evaluating suplied JS on completion:
+
+
+
+
+
+
+
+
+Remote form replacing the forms content after confirming results:
+
+
+
+
+
+
+
+
+Remote form replacing the forms content after running a function:
+
+
+
+
+
+
+
+
+A form with no remote submit (so should not be ajaxified):
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test1.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test1.jsp
new file mode 100644
index 000000000..e3c06ce9e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test1.jsp
@@ -0,0 +1,18 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+
+
+
+
+ Test 1 Form
+
+
+
+test2 - before
+
+test3 - before
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test2.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test2.jsp
new file mode 100644
index 000000000..9eecf5099
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test2.jsp
@@ -0,0 +1,6 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Test 2 form
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test3.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test3.jsp
new file mode 100644
index 000000000..9862ad25b
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remoteforms/test3.jsp
@@ -0,0 +1,8 @@
+
+
+
+
+
+Test 3 Page
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/remotelink/index.jsp b/trunk/apps/showcase/src/main/webapp/ajax/remotelink/index.jsp
new file mode 100644
index 000000000..2e06e8666
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/remotelink/index.jsp
@@ -0,0 +1,112 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Examples
+
+
+
+
+
+One Component:
+Initial Content
+
+
+
+Two Component:
+Initial Content
+
+
+Three Component:
+Initial Content
+
+
+Fourth Component:
+Initial Content
+
+
+
+
+
+
+Remote link 1 updating "One Component" and "Two Component"
+
+Update
+
+
+Remote link 2 updating "Two Component" and "Three Component"
+Update
+
+
+Remote DIV that is not connected to any remote links:
+Initial Content
+
+
+A Remote link that doesn't trigger any remote DIV updates
+
+Update
+
+
+
+A Remote link that will update "Fourth Component"
+Update
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example1.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example1.jsp
new file mode 100644
index 000000000..5769826b4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example1.jsp
@@ -0,0 +1,113 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax examples - tabbled panel
+
+
+ ">
+ ">
+ " media="print">
+ ">
+
+
+
+
+
+
+
+
+
+
+ This is the first pane
+
+
+
+
+
+
+ This is the second panel
+
+
+ This is the three
+
+
+
+
+
+
+ This is the left pane
+
+
+
+
+
+
+
+ middle tab
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Outer one
+
+ Inner 1
+ Inner 2
+ Inner 3
+
+
+
+ Outer two
+
+ Inner 21
+ Inner 22
+ Inner 23
+
+
+
+ Outer three
+
+ Inner 31
+ Inner 32
+ Inner 33
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example2.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example2.jsp
new file mode 100644
index 000000000..ec2d6f688
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example2.jsp
@@ -0,0 +1,52 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax examples - tabbled panel
+
+
+ ">
+ ">
+ " media="print">
+ ">
+
+
+
+
+
+
+
+
+
+
+ This is the first pane
+
+
+
+
+
+
+ This is the second panel
+
+
+ This is the three
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example3.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example3.jsp
new file mode 100644
index 000000000..55dedaa11
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example3.jsp
@@ -0,0 +1,57 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax examples - tabbled panel
+
+
+ ">
+ ">
+ " media="print">
+ ">
+
+
+
+
+
+
+
+
+
+
+
+ This is the left pane
+
+
+
+
+
+
+
+ middle tab
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example4.ftl b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example4.ftl
new file mode 100644
index 000000000..c533d15d0
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example4.ftl
@@ -0,0 +1,18 @@
+
+
+ Example 4
+ <@s.head theme="ajax" debug="false" />
+ " />
+
+
+ <@s.url id="panel1url" action="panel1" namespace="/nodecorate" includeContext="false" />
+ <@s.url id="panel2url" action="panel2" namespace="/nodecorate" includeContext="false"/>
+ <@s.url id="panel3url" action="panel3" namespace="/nodecorate" includeContext="false"/>
+ <@s.tabbedPanel id="tabbedpanel" >
+ <@s.panel id="panel1" tabName="Panel1" remote="true" href="%{#panel1url}" theme="ajax" />
+ <@s.panel id="panel2" tabName="Panel2" remote="true" href="%{#panel2url}" theme="ajax" />
+ <@s.panel id="panel3" tabName="Panel3" remote="true" href="%{#panel3url}" theme="ajax" />
+ @s.tabbedPanel>
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5.jsp
new file mode 100644
index 000000000..770b353cd
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5.jsp
@@ -0,0 +1,27 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Insert title here
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5Ok.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5Ok.jsp
new file mode 100644
index 000000000..5c3b801ee
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/example5Ok.jsp
@@ -0,0 +1,9 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+OK
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/index.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/index.jsp
new file mode 100644
index 000000000..7c501dfe7
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/index.jsp
@@ -0,0 +1,33 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Tabbed Panes
+ <%@ include file="/ajax/commonInclude.jsp" %>
+
+
+
+
+Examples
+
+
+
+ A local tabbed panel
+ A remote and local tabbed panel
+ Various remote and local tabbed panels (with enclosed tabbed pannels)
+
+
+ Only remove tabbed panel
+
+
+
+ Remote form validation inside tabbed panel
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel1.ftl b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel1.ftl
new file mode 100644
index 000000000..601c06058
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel1.ftl
@@ -0,0 +1,3 @@
+
+Hello,
+Today is ${todayDate}, the time now is ${todayTime}
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2.ftl b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2.ftl
new file mode 100644
index 000000000..b027ee088
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2.ftl
@@ -0,0 +1,7 @@
+
+
+
+<@s.form action="panel2Submit" namespace="/nodecorate" theme="ajax">
+ <@s.textfield label="Name" name="name" theme="ajax" />
+ <@s.submit theme="ajax" resultDivId="result" />
+@s.form>
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2Submit.ftl b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2Submit.ftl
new file mode 100644
index 000000000..34e4e0d15
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel2Submit.ftl
@@ -0,0 +1,2 @@
+
+Hello, ${name}
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3.ftl b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3.ftl
new file mode 100644
index 000000000..1d0a374b4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3.ftl
@@ -0,0 +1,9 @@
+
+
+
+
+<@s.form action="panel3Submit" namespace="/nodecorate" theme="ajax">
+ <@s.select label="Gender" name="gender" list=r"%{#{'Male':'Male','Female':'Female'}}" theme="ajax" />
+ <@s.submit theme="ajax" resultDivId="result" />
+@s.form>
+
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3Submit.ftl b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3Submit.ftl
new file mode 100644
index 000000000..ee436e125
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tabbedpanel/nodecorate/panel3Submit.ftl
@@ -0,0 +1,2 @@
+
+So, you are a ${gender}
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/testjs.jsp b/trunk/apps/showcase/src/main/webapp/ajax/testjs.jsp
new file mode 100644
index 000000000..5223ef707
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/testjs.jsp
@@ -0,0 +1,14 @@
+<%
+ request.setAttribute("decorator", "none");
+ response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
+ response.setHeader("Pragma","no-cache"); //HTTP 1.0
+ response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
+%>
+
+
+Show me some text also
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tree/getCategory.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tree/getCategory.jsp
new file mode 100644
index 000000000..1cdf2801e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tree/getCategory.jsp
@@ -0,0 +1,24 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<%@include file="partialChunkHeader.jsp"%>
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tree/partialChunkHeader.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tree/partialChunkHeader.jsp
new file mode 100644
index 000000000..01113d688
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tree/partialChunkHeader.jsp
@@ -0,0 +1,6 @@
+<%
+ request.setAttribute("decorator", "none");
+ response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
+ response.setHeader("Pragma","no-cache"); //HTTP 1.0
+ response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
+%>
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tree/toggle.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tree/toggle.jsp
new file mode 100644
index 000000000..35010bb5e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tree/toggle.jsp
@@ -0,0 +1,12 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+<%@include file="partialChunkHeader.jsp"%>
+<%
+ response.setContentType("text/javascript");
+%>
+dojo.event.topic.publish("children_ ");
+var d = document.getElementById("children_ ");
+if (d.style.display != "none") {
+ d.style.display = "none";
+} else {
+ d.style.display = "";
+}
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/tree/tree.jsp b/trunk/apps/showcase/src/main/webapp/ajax/tree/tree.jsp
new file mode 100644
index 000000000..6d8e18c34
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/tree/tree.jsp
@@ -0,0 +1,13 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Tree
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/ajax/widgets/index.jsp b/trunk/apps/showcase/src/main/webapp/ajax/widgets/index.jsp
new file mode 100644
index 000000000..b9f6afeee
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/ajax/widgets/index.jsp
@@ -0,0 +1,36 @@
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Ajax Widgets
+
+
+
+
+NOTES:
+
+ Make sure that there is a 'value' attribute in the textarea with the content for the editor
+ This is experimental
+
+
+Default Editor configuration:
+
+
+
+
+
+
+Configured Editor configuration:
+
+
+ textGroup;|;justifyGroup;|;listGroup;|;indentGroup
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/chatLogin.ftl b/trunk/apps/showcase/src/main/webapp/chat/chatLogin.ftl
new file mode 100644
index 000000000..1dfa3ca8c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/chatLogin.ftl
@@ -0,0 +1,16 @@
+
+
+
+ Showcase - Chat - Login
+ <@s.head theme="ajax" />
+
+
+ <@s.actionerror />
+ <@s.actionmessage />
+ <@s.fielderror />
+ <@s.form action="login" namespace="/chat" method="POST">
+ <@s.textfield name="name" label="Name" required="true" />
+ <@s.submit/>
+ @s.form>
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/createRoom.ftl b/trunk/apps/showcase/src/main/webapp/chat/createRoom.ftl
new file mode 100644
index 000000000..fbe71cc91
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/createRoom.ftl
@@ -0,0 +1,2 @@
+<@s.actionerror />
+<@s.fielderror />
diff --git a/trunk/apps/showcase/src/main/webapp/chat/index.jsp b/trunk/apps/showcase/src/main/webapp/chat/index.jsp
new file mode 100644
index 000000000..b58d7a302
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/index.jsp
@@ -0,0 +1,3 @@
+
+<% response.sendRedirect("main.action"); %>
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/messagesAvailableInRoom.ftl b/trunk/apps/showcase/src/main/webapp/chat/messagesAvailableInRoom.ftl
new file mode 100644
index 000000000..2550dcd2d
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/messagesAvailableInRoom.ftl
@@ -0,0 +1,33 @@
+
+
+
+<@s.iterator id="message" value="%{messagesAvailableInRoom}" status="stat">
+
+ <#if stat.odd>
+
+ <#else>
+
+ #if>
+ <@s.property value="%{#message.creator.name}" />
+
+ <#if stat.odd>
+
+ <#else>
+
+ #if>
+ <@s.property value="%{#message.creationDate}" />
+
+ <#if stat.odd>
+
+ <#else>
+
+ #if>
+ <@s.property value="%{#message.message}" />
+
+
+@s.iterator>
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/roomSelection.ftl b/trunk/apps/showcase/src/main/webapp/chat/roomSelection.ftl
new file mode 100644
index 000000000..2af660821
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/roomSelection.ftl
@@ -0,0 +1,163 @@
+
+
+
+
+ Showcase - Chat - Room Selection
+ <@s.head theme="ajax" />
+
+
+
+
+
+
+
+
+
Operations
+ <@s.url id="url" action="logout" namespace="/chat" />
+
+ <@s.a href="%{#url}">Logout@s.a>
+
+
+ <#if (actionErrors?size gt 0)>
+
+
Action Errors
+ <@s.actionerrors />
+
+ #if>
+
+
Users Available In Chat
+ <@s.div id="usersAvailable" delay="1" updateFreq="%{@org.apache.struts2.showcase.chat.Constants@UPDATE_FREQ}"
+ theme="ajax" href="/chat/ajax/usersAvailable.action"
+ class="box">
+ Initial Loading Users ...
+ @s.div>
+
+
+
+
+
+
+
Rooms Available In Chat
+ <@s.div id="roomsAvailable" listenTopics="topicRoomCreated"
+ delay="1" updateFreq="%{@org.apache.struts2.showcase.chat.Constants@UPDATE_FREQ}"
+ theme="ajax" href="/chat/ajax/roomsAvailable.action" >
+ Initial Loading Rooms ...
+ @s.div>
+
+
+
+
Create Room In Chat
+
+ <@s.form id="createRoomId" action="createRoom" namespace="/chat/ajax" method="POST" theme="ajax">
+ <@s.textfield label="Room Name" required="true" name="name" />
+ <@s.textarea theme="xhtml" label="Room Description" required="true" name="Description" />
+ <@s.submit value="%{'Create Room'}" resultDivId="createRoomResult" notifyTopics="topicRoomCreated" theme="ajax" align="left" />
+ @s.form>
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/roomsAvailable.ftl b/trunk/apps/showcase/src/main/webapp/chat/roomsAvailable.ftl
new file mode 100644
index 000000000..1d343c00e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/roomsAvailable.ftl
@@ -0,0 +1,44 @@
+
+
+
+<@s.iterator id="room" value="%{availableRooms}" status="stat">
+
+ <#if stat.isOdd()>
+
+ <#else>
+
+ #if>
+ <@s.url id="url" action="enterRoom" namespace="/chat">
+ <@s.param name="roomName" value="%{#room.name}" />
+ @s.url>
+ <@s.a href="%{url}">Enter@s.a>
+
+ <#if stat.odd>
+
+ <#else>
+
+ #if>
+ <@s.property value="%{#room.name}" />
+
+ <#if stat.odd>
+
+ <#else>
+
+ #if>
+ <@s.property value="%{#room.description}" />
+
+ <#if stat.odd>
+
+ <#else>
+
+ #if>
+ <@s.property value="%{#room.creationDate}" />
+
+
+@s.iterator>
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/sendMessageToRoomResult.ftl b/trunk/apps/showcase/src/main/webapp/chat/sendMessageToRoomResult.ftl
new file mode 100644
index 000000000..c75d32bca
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/sendMessageToRoomResult.ftl
@@ -0,0 +1,2 @@
+
+<@s.fielderror />
diff --git a/trunk/apps/showcase/src/main/webapp/chat/showRoom.ftl b/trunk/apps/showcase/src/main/webapp/chat/showRoom.ftl
new file mode 100644
index 000000000..e04a404cd
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/showRoom.ftl
@@ -0,0 +1,160 @@
+
+
+
+ Showcase - Chat - Show Room
+ <@s.head theme="ajax" />
+
+
+
+
+
+
+
Operation
+ <@s.url id="url" action="exitRoom" namespace="/chat">
+ <@s.param name="roomName" value="%{roomName}" />
+ @s.url>
+
+ <@s.a href="%{#url}">Exit Room@s.a>
+
+
+
+
Users Available In Chat
+ <@s.div id="usersAvailable" href="/chat/ajax/usersAvailable.action"
+ theme="ajax" delay="1" updateFreq="%{@org.apache.struts2.showcase.chat.Constants@UPDATE_FREQ}">
+ Initial Users Available ...
+ @s.div>
+
+
+
+
+
+
Messages Posted In Room [${roomName?default('')}]
+ <@s.url id="url" value="/chat/ajax/messagesAvailableInRoom.action" includeContext="false">
+ <@s.param name="roomName" value="%{roomName}" />
+ @s.url>
+ <@s.div id="messagesInRoom" href="%{#url}" includeContext="false"
+ theme="ajax" delay="1" updateFreq="%{@org.apache.struts2.showcase.chat.Constants@UPDATE_FREQ}"
+ listenTopics="topicMessageSend">
+ Initial Messages In Room ...
+ @s.div>
+
+
+
+
Send Messages
+ <@s.form id="sendMessageForm" action="sendMessageToRoom" namespace="/chat/ajax" method="POST" theme="ajax">
+
+ <@s.textarea label="Message"name="message" theme="xhtml" />
+ <@s.hidden name="roomName" value="%{roomName}" />
+ <@s.submit id="submit" theme="ajax" resultDivId="sendMessageResult" notifyTopics="topicMessageSend" value="%{'Send'}" />
+ @s.form>
+
+
+
+
+
+
+
Users Available In Room [${roomName?default('')}]
+ <@s.url id="url" value="/chat/ajax/usersAvailableInRoom.action" includeContext="false">
+ <@s.param name="roomName" value="%{roomName}" />
+ @s.url>
+ <@s.div id="usersAvailableInRoom" href="%{#url}" includeContext="false"
+ theme="ajax" delay="1" updateFreq="%{@org.apache.struts2.showcase.chat.Constants@UPDATE_FREQ}">
+ Initial Users Available In Room ...
+ @s.div>
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/usersAvailable.ftl b/trunk/apps/showcase/src/main/webapp/chat/usersAvailable.ftl
new file mode 100644
index 000000000..e03fa37d0
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/usersAvailable.ftl
@@ -0,0 +1,6 @@
+
+
+<#list availableUsers as user>
+ ${user.name}
+#list>
+
diff --git a/trunk/apps/showcase/src/main/webapp/chat/usersAvailableInRoom.ftl b/trunk/apps/showcase/src/main/webapp/chat/usersAvailableInRoom.ftl
new file mode 100644
index 000000000..95822bf7a
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/chat/usersAvailableInRoom.ftl
@@ -0,0 +1,8 @@
+
+
+<@s.iterator id="member" value="%{usersAvailableInRoom}">
+ <@s.property value="%{#member.name}" />
+@s.iterator>
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/continuations/guess.ftl b/trunk/apps/showcase/src/main/webapp/continuations/guess.ftl
new file mode 100644
index 000000000..453b0b9a5
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/continuations/guess.ftl
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+<#list actionMessages as msg>
+ ${msg}
+#list>
+
+<@s.form action="guess" method="post">
+ <@s.textfield label="Guess" name="guess"/>
+ <@s.submit value="Guess"/>
+@s.form>
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/Address.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/Address.java.txt
new file mode 100644
index 000000000..bf501834e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/Address.java.txt
@@ -0,0 +1,35 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+
+/**
+ * @version $Date$ $Id$
+ */
+public class Address {
+
+ private String id;
+ private String address;
+
+ public String getId() { return id; }
+ public void setId(String id) { this.id = id; }
+
+ public String getAddress() { return address; }
+ public void setAddress(String address) { this.address = address; }
+
+}
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/AddressAction.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/AddressAction.java.txt
new file mode 100644
index 000000000..35f17f5fd
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/AddressAction.java.txt
@@ -0,0 +1,44 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * @version $Date$ $Id$
+ */
+public class AddressAction extends ActionSupport {
+
+ private Set addresses = new LinkedHashSet();
+
+ public Set getAddresses() { return addresses; }
+ public void setAddresses(Set addresses) { this.addresses = addresses; }
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ System.out.println(addresses);
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/EnumTypeConverter.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/EnumTypeConverter.java.txt
new file mode 100644
index 000000000..0a1b1aa38
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/EnumTypeConverter.java.txt
@@ -0,0 +1,55 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.struts2.util.StrutsTypeConverter;
+
+/**
+ * @version $Date$ $Id$
+ */
+public class EnumTypeConverter extends StrutsTypeConverter {
+
+ @Override
+ public Object convertFromString(Map context, String[] values, Class toClass) {
+ List result = new ArrayList();
+ for (int a=0; a< values.length; a++) {
+ Enum e = Enum.valueOf(OperationsEnum.class, values[a]);
+ if (e != null)
+ result.add(e);
+ }
+ return result;
+ }
+
+ @Override
+ public String convertToString(Map context, Object o) {
+ List l = (List) o;
+ String result ="<";
+ for (Iterator i = l.iterator(); i.hasNext(); ) {
+ result = result + "["+ i.next() +"]";
+ }
+ result = result+">";
+ return result;
+ }
+
+
+}
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnum.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnum.java.txt
new file mode 100644
index 000000000..2db119448
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnum.java.txt
@@ -0,0 +1,30 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+/**
+ *
+ * @version $Date$ $Id$
+ */
+public enum OperationsEnum {
+ ADD,
+ MINUS,
+ DIVIDE,
+ MULTIPLY,
+ REMAINDER;
+}
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumAction.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumAction.java.txt
new file mode 100644
index 000000000..ee2327ff3
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumAction.java.txt
@@ -0,0 +1,53 @@
+/*
+ * $Id: Person.java 440597 2006-09-06 03:34:39Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ * @version $Date$ $Id$
+ */
+public class OperationsEnumAction extends ActionSupport {
+
+ private static final long serialVersionUID = -2229489704988870318L;
+
+ private List selectedOperations = new LinkedList();
+
+ public List getSelectedOperations() { return this.selectedOperations; }
+ public void setSelectedOperations(List selectedOperations) {
+ this.selectedOperations = selectedOperations;
+ }
+
+
+ public List getAvailableOperations() {
+ return Arrays.asList(OperationsEnum.values());
+ }
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
+
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumActionConversion.txt b/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumActionConversion.txt
new file mode 100644
index 000000000..621beafba
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/OperationsEnumActionConversion.txt
@@ -0,0 +1,4 @@
+
+selectedOperations=org.apache.struts2.showcase.conversion.EnumTypeConverter
+Element_selectedOperations=org.apache.struts2.showcase.conversion.OperationsEnum
+
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/Person.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/Person.java.txt
new file mode 100644
index 000000000..2ce9e0fdb
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/Person.java.txt
@@ -0,0 +1,34 @@
+/*
+ * $Id: AbstractDao.java 394498 2006-04-16 15:28:06Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.io.Serializable;
+
+/**
+ *
+ */
+public class Person implements Serializable {
+ private String name;
+ private Integer age;
+
+ public void setName(String name) { this.name = name; }
+ public String getName() { return this.name; }
+
+ public void setAge(Integer age) { this.age = age; }
+ public Integer getAge() { return this.age; }
+}
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/PersonAction.java.txt b/trunk/apps/showcase/src/main/webapp/conversion/PersonAction.java.txt
new file mode 100644
index 000000000..015fab018
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/PersonAction.java.txt
@@ -0,0 +1,43 @@
+/*
+ * $Id: AbstractDao.java 394498 2006-04-16 15:28:06Z tmjee $
+ *
+ * Copyright 2006 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.
+ */
+package org.apache.struts2.showcase.conversion;
+
+import java.util.List;
+
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ *
+ */
+public class PersonAction extends ActionSupport {
+
+ private List persons;
+
+ public List getPersons() { return persons; }
+ public void setPersons(List persons) { this.persons = persons; }
+
+
+
+ public String input() throws Exception {
+ return SUCCESS;
+ }
+
+ public String submit() throws Exception {
+ return SUCCESS;
+ }
+}
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/enterAddressInfo.jsp b/trunk/apps/showcase/src/main/webapp/conversion/enterAddressInfo.jsp
new file mode 100644
index 000000000..2d028a869
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/enterAddressInfo.jsp
@@ -0,0 +1,48 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Showcase - Conversion - Set
+
+
+
+
+An example populating a Set of object (Address.java) into Struts' action (AddressAction.java)
+
+
+
+See the jsp code here.
+See the code for PersonAction.java here.
+See the code for Person.java here.
+
+
+
+
+
+
+
+
+
+
+ <%--
+ The following is how its done statically
+ --%>
+ <%--
+
+
+
+
+
+
+ --%>
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/enterOperations.jsp b/trunk/apps/showcase/src/main/webapp/conversion/enterOperations.jsp
new file mode 100644
index 000000000..c01d6489b
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/enterOperations.jsp
@@ -0,0 +1,31 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Showcase - Conversion - Tiger 5 Enum
+
+
+
+See the jsp code here.
+See the code for OperationsEnum.java here.
+See the code for OperationsEnumAction.java here.
+See the code for EnumTypeConverter.java here.
+See the properties for OperationsEnumAction-conversion.properties here.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/enterPersonInfo.jsp b/trunk/apps/showcase/src/main/webapp/conversion/enterPersonInfo.jsp
new file mode 100644
index 000000000..8e9c54166
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/enterPersonInfo.jsp
@@ -0,0 +1,58 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+Showcase - Conversion - Populate Object into Struts' action List
+
+
+
+
+An example populating a list of object (Person.java) into Struts' action (PersonAction.java)
+
+
+
+See the jsp code here.
+See the code for PersonAction.java here.
+See the code for Person.java here.
+
+
+
+
+
+
+
+ <%--
+ The following is done Dynamically
+ --%>
+
+
+
+
+
+
+
+ <%--
+ The following is done statically:-
+ --%>
+ <%--
+
+
+
+
+
+
+ --%>
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/index.jsp b/trunk/apps/showcase/src/main/webapp/conversion/index.jsp
new file mode 100644
index 000000000..69f17c460
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/index.jsp
@@ -0,0 +1,26 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Showcase - Conversion
+
+
+
+
+
+
+ Populate into the Struts action class a List of Person.java Object
+
+
+
+ Populate into Struts action class a Set of Address.java Object
+
+
+
+ Populate into Struts action class a List of OperationEnum.java (Java5 Enum)
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/showAddressInfo.jsp b/trunk/apps/showcase/src/main/webapp/conversion/showAddressInfo.jsp
new file mode 100644
index 000000000..2f1d4e346
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/showAddressInfo.jsp
@@ -0,0 +1,15 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Showcase - Conversion - Set
+
+
+
+ ->
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/showOperations.jsp b/trunk/apps/showcase/src/main/webapp/conversion/showOperations.jsp
new file mode 100644
index 000000000..c4b885903
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/showOperations.jsp
@@ -0,0 +1,17 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Showcase - Conversion - Tiger 5 Enum
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/trunk/apps/showcase/src/main/webapp/conversion/showPersonInfo.jsp b/trunk/apps/showcase/src/main/webapp/conversion/showPersonInfo.jsp
new file mode 100644
index 000000000..b0b10e1b1
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/conversion/showPersonInfo.jsp
@@ -0,0 +1,17 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+
+Showcase - Conversion - Populate Object into Struts action List
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/ftlCustomTemplate.ftl b/trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/ftlCustomTemplate.ftl
new file mode 100644
index 000000000..415233443
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/ftlCustomTemplate.ftl
@@ -0,0 +1,7 @@
+
+
+Freemarker Custom Template -
+parameter 'paramName' - ${parameters.paramName}
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/jspCustomTemplate.jsp b/trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/jspCustomTemplate.jsp
new file mode 100644
index 000000000..311c32987
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/customTemplateDir/customTheme/jspCustomTemplate.jsp
@@ -0,0 +1,8 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+JSP Custom Template -
+parameter 'paramName' -
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/date.jsp b/trunk/apps/showcase/src/main/webapp/date.jsp
new file mode 100644
index 000000000..400cd6d24
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/date.jsp
@@ -0,0 +1,2 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
diff --git a/trunk/apps/showcase/src/main/webapp/empmanager/editEmployee.jsp b/trunk/apps/showcase/src/main/webapp/empmanager/editEmployee.jsp
new file mode 100644
index 000000000..fb432e66b
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/empmanager/editEmployee.jsp
@@ -0,0 +1,41 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ">
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/empmanager/editSkill.jsp b/trunk/apps/showcase/src/main/webapp/empmanager/editSkill.jsp
new file mode 100644
index 000000000..a5544b0ca
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/empmanager/editSkill.jsp
@@ -0,0 +1,27 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <%--s:submit name="%{#submitType}" value="%{getText('save')}" /--%>
+
+
+ ">
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/empmanager/index.jsp b/trunk/apps/showcase/src/main/webapp/empmanager/index.jsp
new file mode 100644
index 000000000..b128df60c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/empmanager/index.jsp
@@ -0,0 +1,21 @@
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+Showcase - CRUD
+
+
+ CRUD
+
+
+
+ List available Skills
+ Create/Edit Skill
+ List available Employees
+ Create/Edit Employee
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/empmanager/listEmployees.jsp b/trunk/apps/showcase/src/main/webapp/empmanager/listEmployees.jsp
new file mode 100644
index 000000000..356bd0af4
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/empmanager/listEmployees.jsp
@@ -0,0 +1,26 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+Available Employees
+
+
+Available Employees
+
+
+ Id
+ First Name
+ Last Name
+
+
+
+ ">
+
+
+
+
+
+ ">Create new Employee
+ ">Back to Showcase Startpage
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/empmanager/listSkills.jsp b/trunk/apps/showcase/src/main/webapp/empmanager/listSkills.jsp
new file mode 100644
index 000000000..3b1f77965
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/empmanager/listSkills.jsp
@@ -0,0 +1,24 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+
+Available Skills
+
+
+Available Skills
+
+
+ Name Description
+
+
+
+ ">
+
+
+
+
+
+ ">Create new Skill
+ ">Back to Showcase Startpage
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/filedownload/index.jsp b/trunk/apps/showcase/src/main/webapp/filedownload/index.jsp
new file mode 100644
index 000000000..0bd107e2c
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/filedownload/index.jsp
@@ -0,0 +1,14 @@
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Showcase
+
+
+
+ File Download Example
+
+ Click this link to download Struts logo.
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/fileupload/upload-success.jsp b/trunk/apps/showcase/src/main/webapp/fileupload/upload-success.jsp
new file mode 100644
index 000000000..15029cb54
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/fileupload/upload-success.jsp
@@ -0,0 +1,25 @@
+<%@ page
+ language="java"
+ contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Showcase
+
+
+
+Fileupload sample
+
+
+
+ ContentType:
+ FileName:
+ File:
+ Caption:
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/fileupload/upload.jsp b/trunk/apps/showcase/src/main/webapp/fileupload/upload.jsp
new file mode 100644
index 000000000..c683014d8
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/fileupload/upload.jsp
@@ -0,0 +1,21 @@
+<%@ page
+ language="java"
+ contentType="text/html; charset=UTF-8"
+ pageEncoding="UTF-8"%>
+<%@ taglib prefix="s" uri="/struts-tags" %>
+
+
+ Showcase
+
+
+
+ Fileupload sample
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/freemarker/customFreemarkerManagerUsage.ftl b/trunk/apps/showcase/src/main/webapp/freemarker/customFreemarkerManagerUsage.ftl
new file mode 100644
index 000000000..23f2b5963
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/freemarker/customFreemarkerManagerUsage.ftl
@@ -0,0 +1,26 @@
+
+
+
+ Showcase - Freemarker - CustomFreemarkerManager Usage
+
+
+ Custom Freemarker Manager Usage
+
+
+ This page shows a simple example of using a custom freemarker manager.
+ The custom freemarker manager put into freemarker model an util classed
+ under the name 'customFreemarkerManagerUtil'. so one could use
+
+
+ $ { customFreemarkerManagerUtil.getTodayDate() } - to get today's date
+ $ { customFreemarkerManagerUtil.todayDate } - to get today's date
+ $ { customFreemarkerManagerUtil.getTimeNow() } - to get the time now
+ $ { customFreemarkerManagerUtil.timeNow } - to get the time now
+
+
+ Today's Date = ${customFreemarkerManagerUtil.todayDate}
+ Time now = ${customFreemarkerManagerUtil.getTimeNow()}
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/freemarker/index.jsp b/trunk/apps/showcase/src/main/webapp/freemarker/index.jsp
new file mode 100644
index 000000000..1f6084e7e
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/freemarker/index.jsp
@@ -0,0 +1,20 @@
+
+<%@taglib prefix="s" uri="/struts-tags" %>
+
+
+
+ Showcase - Freemarker
+
+
+
+
+
+
+ Demo of usage of a Custom Freemarker Manager
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/blank.ftl b/trunk/apps/showcase/src/main/webapp/hangman/blank.ftl
new file mode 100644
index 000000000..e69de29bb
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/hangmanAjax.ftl b/trunk/apps/showcase/src/main/webapp/hangman/hangmanAjax.ftl
new file mode 100644
index 000000000..1845984b9
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/hangman/hangmanAjax.ftl
@@ -0,0 +1,232 @@
+
+
+
+ Showcase - Hangman
+ <@s.head theme="ajax" debug="false" />
+
+
+
+
+
+
+
+
+ <@s.url id="url" value="/hangman/images/hangman.png" />
+ "
+ width="197" height="50" border="0"/>
+
+
+ <#-- Guesses Left -->
+
+ <@s.set name="guessLeftImageName" value="%{'Chalkboard_'+hangman.guessLeft()+'.png'}" />
+ <@s.url id="url" value="%{'/hangman/images/'+#guessLeftImageName}" />
+
" width="20" height="20" border="0" />
+
+
+
+ <@s.url id="url" value="/hangman/images/guesses-left.png" />
+ " width="164" height="11" border="0"/>
+
+
+
+
+
+ <#-- Display Scaffold -->
+
+ <@s.set name="scaffoldImageName" value="%{'scaffold_'+hangman.guessLeft()+'.png'}" />
+ <@s.url id="url" value="%{'/hangman/images/'+#scaffoldImageName}" />
+
" border="0"/>
+
+
+
+
+
+
+
+ <@s.url id="url" value="/hangman/images/guess.png" />
+ "
+ align="MIDDLE" width="127" height="20" border="0"/>
+
+
+ <#-- Display Vacab -->
+
+ <@s.iterator id="currentCharacter" value="%{hangman.vocab.inCharacters()}" stat="stat">
+ <#if hangman.characterGuessedBefore(currentCharacter)>
+ <@s.set name="chalkboardImageName" value="%{'Chalkboard_'+#currentCharacter.toString()+'.png'}" />
+ <@s.url id="url" value="%{'/hangman/images/'+#chalkboardImageName}" />
+
"
+ src="<@s.property value="%{#url}" />" width="36" border="0"/>
+ <#else>
+ <@s.url id="url" value="/hangman/images/Chalkboard_underscroll.png" />
+
" width="36" border="0"/>
+ #if>
+ @s.iterator>
+
+
+
+
+
+
+ <@s.url id="url" value="/hangman/images/choose.png" />
+ "
+ height="20" width="151" border="0"/>
+
+
+
+
+ <#-- Show Characters Available -->
+
+ <@s.iterator id="currentCharacter" value="%{hangman.charactersAvailable}" status="stat">
+ <@s.set name="chalkboardImageName" value="%{'Chalkboard_'+#currentCharacter+'.png'}" />
+ <@s.url id="chalkboardImageUrl" value="%{'/hangman/images/'+#chalkboardImageName}" />
+ <@s.url id="spacerUrl" value="/hangman/images/letter-spacer.png" />
+
+ <@s.a theme="ajax"
+ href="ajax/blank.action"
+ id="%{#currentCharacter}"
+ notifyTopics="topicGuessMade"
+ showErrorTransportText="true">
+
" width="36" border="0" />
+ @s.a>
+ @s.iterator>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/hangmanMenu.ftl b/trunk/apps/showcase/src/main/webapp/hangman/hangmanMenu.ftl
new file mode 100644
index 000000000..82bd032a2
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/hangman/hangmanMenu.ftl
@@ -0,0 +1,18 @@
+
+
+
+ Showcase - Hangman - Menu
+
+
+
+
+ <@s.url id="url" action="hangmanAjax" namespace="/hangman" />
+ <@s.a href="%{#url}">Hangman (Ajax)@s.a>
+
+
+ <@s.url id="url" action="hangmanNonAjax" namespace="/hangman" />
+ <@s.a href="%{#url}">Hangman (Non Ajax)@s.a>
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/hangmanNonAjax.ftl b/trunk/apps/showcase/src/main/webapp/hangman/hangmanNonAjax.ftl
new file mode 100644
index 000000000..73419f17f
--- /dev/null
+++ b/trunk/apps/showcase/src/main/webapp/hangman/hangmanNonAjax.ftl
@@ -0,0 +1,135 @@
+
+
+ Showcase - Hangman
+ <@s.head theme="xhtml" />
+
+
+
+
+
+ <@s.url id="url" value="/hangman/images/hangman.png" />
+ "
+ width="197" height="50" border="0"/>
+
+
+ <#-- Guesses Left -->
+
+ <#if (hangman.guessLeft() >= 0)>
+ <@s.set name="guessLeftImageName" value="%{'Chalkboard_'+hangman.guessLeft()+'.png'}" />
+ <@s.url id="url" value="%{'/hangman/images/'+#guessLeftImageName}" />
+
" width="20" height="20" border="0" />
+ #if>
+
+
+
+ <@s.url id="url" value="/hangman/images/guesses-left.png" />
+ " width="164" height="11" border="0"/>
+
+
+
+
+
+ <#-- Display Scaffold -->
+
+ <@s.set name="scaffoldImageName" value="%{'scaffold_'+hangman.guessLeft()+'.png'}" />
+ <@s.url id="url" value="%{'/hangman/images/'+#scaffoldImageName}" />
+
" border="0"/>
+
+
+
+
+
+
+
+ <@s.url id="url" value="/hangman/images/guess.png" />
+ "
+ align="MIDDLE" width="127" height="20" border="0"/>
+
+
+ <#-- Display Vacab -->
+
+ <#if hangman.gameEnded()>
+ <@s.iterator id="currentCharacter" value="%{hangman.vocab.inCharacters()}" stat="stat">
+ <@s.url id="url" value="%{'/hangman/images/Chalkboard_'+#currentCharacter.toString()+'.png'}" />
+
"
+ src="<@s.property value="%{#url}" />" width="36" border="0" />
+ @s.iterator>
+ <#else>
+ <@s.iterator id="currentCharacter" value="%{hangman.vocab.inCharacters()}" stat="stat">
+ <#if hangman.characterGuessedBefore(currentCharacter)>
+ <@s.set name="chalkboardImageName" value="%{'Chalkboard_'+#currentCharacter.toString()+'.png'}" />
+ <@s.url id="url" value="%{'/hangman/images/'+#chalkboardImageName}" />
+
"
+ src="<@s.property value="%{#url}" />" width="36" border="0"/>
+ <#else>
+ <@s.url id="url" value="/hangman/images/Chalkboard_underscroll.png" />
+
" width="36" border="0"/>
+ #if>
+ @s.iterator>
+ #if>
+
+
+
+
+
+
+ <@s.url id="url" value="/hangman/images/choose.png" />
+ "
+ height="20" width="151" border="0"/>
+
+
+
+
+ <#-- Show Characters Available -->
+
+ <#if hangman.gameEnded()>
+ <@s.set name="winImageName" value="%{'you-win.png'}" />
+ <@s.set name="looseImageName" value="%{'you-lose.png'}" />
+ <@s.set name="startImageName" value="%{'start.png'}" />
+ <@s.url id="winImageUrl" value="%{'/hangman/images/'+#winImageName}" />
+ <@s.url id="looseImageUrl" value="%{'/hangman/images/'+#looseImageName}" />
+ <@s.url id="startImageUrl" value="%{'/hangman/images/'+#startImageName}" />
+ <@s.url id="startHref" action="hangmanNonAjax" namespace="/hangman" />
+
+ <#if hangman.isWin()>
+
" width="341" height="44" />
+ <#else>
+
" width="381" height="44" />
+ #if>
+ <@s.a href="%{#startHref}">
+
" width="250" height="43" />
+ @s.a>
+ <#else>
+ <@s.iterator id="currentCharacter" value="%{hangman.charactersAvailable}" status="stat">
+ <@s.set name="chalkboardImageName" value="%{'Chalkboard_'+#currentCharacter+'.png'}" />
+ <@s.url id="chalkboardImageUrl" value="%{'/hangman/images/'+#chalkboardImageName}" />
+ <@s.url id="spacerUrl" value="/hangman/images/letter-spacer.png" />
+ <@s.url id="url" action="guessCharacterNonAjax" namespace="/hangman">
+ <@s.param name="character" value="%{#currentCharacter}" />
+ @s.url>
+
+ <@s.a href="%{#url}"
+ id="%{#currentCharacter}"
+ >
+
" width="36" border="0" />
+ @s.a>
+ @s.iterator>
+ #if>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_0.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_0.png
new file mode 100644
index 0000000000000000000000000000000000000000..7485012ddb6ae76bbb31d3a109bd9073a6b6b23e
GIT binary patch
literal 1307
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDt)MP5dj5eSU
zXMsm#F#`kF2M}g-T4OQ;D9DoT=69sJr_5P9XU^6+
zOSdjvyLau@y<4{)+q(DI-o5Ac9y@pJ*tKKluAMt~@7%R}*X{wq^Lx*M;QjOWK=A$j
zcOdxx{r@N!4S_)r0{YkbW&-mDV@Z%-FoVOh8)-oHL{AsTkcwM-L*8zBq`;HfwT-9w
z>Z>VR!_al(z4YC->>iq8jsjKXN1q&AHK8
ze){svkjO>>wP{y9zIgx1VAsy?exNx;G?qKov*QT!b=7Mf)4Z-JB&yqO;nGlC6n|cj
zx78qA_T9qRvUp9WT5iivN8{P-r#lrrXt=pX-t5IWnJM!x{XQV_#wu4%*(hn*l-#W)
zZ#nhFI=>Zj6g}G}y})4d+z$~oXWAvFnjP&g$&XIERkxJs4A-Mo2Ax08ImZc|*rb2P
zx@^sq;^?s4g;DNmt}NW4buU@|-TCLv`v20ZWr1Fy^$sWQZLfKGVeTB`O+Uph%dGQK
zVexpQ+*G+bVr#?Ag;#^L?kXFc+yC;)QG*=@mv8z{oK&rQ_48WWmro-jXR%c{<~A67
z<5%eSNdMY$k-a}*x>r$a|k%)r37@MeS!ki%Z$>FdgVnUPDtjAh1`-!Fke
zoCO|{#S9EwA3&JVX^qJYpdd@Sqpu?a!^VE@KZ&di49pAxJ|V77$xdF`UO~k{QN>YF
z)ltdS$;mCr*)7@GJ=w)Q#l=&KtEW`AOlfJE)6z4ir)O!;l%-RqterAv?VLGV=Pcd2
zbnV`?Tla3=dTi_7V|(|W+k5QXv18Ycox67K+`V(x?p?bF1kdk12ZHy{-vhz-_uqlw
z|M&l+U^D~F!S3}z)*q{Q
zC0#6$x73}*Mdd)}hhMwiBrIT;Z8n_qm;Xah=k=)XXC-RIU*!hBIVD^*EAdI${IV5~
zj&ua<+i<<_w9gjdL*J$OpUGCWl)L6$`LfPq%d`upuDkx}xb-vZvyFDki7qRb?@p4D
zid>N@s;j;xZ&2UElbGnRE^PJ3>A4&)*7UFYBkZ0EJ@@+bC2s<{Y;|G9GLO1SR7
bYsKkD&&baErqkgL3|IzFS3j3^P6|k%)r37@MeS!ki%Z$>FdgVnUPDt%vixQ?io;s
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!@pZSCpe7*cWT=;YUZO$Gw3(R$a|3Vm4*
zE}N;l<#OeJ^E*nLG`iGw+y4=|^zey~q+jDk?V1>kxJ~Y5?K;c4G!pygtS!E5X4~sJ
zt-f;GseNaUE3Iw#vE`%Tzg`fx9$Za*-pp1oU?DWl;u5H
zzS#9ejG^@dp`K6!^LcG64OZpl`4~-&D5^bi-k{yMB!=(&WNX=4MvH3S#44q~dUuW;pTD~D>4VhUiw{@ju38ho<$vuGOUDhAc|JZ
zY$M1hqOcwlW;q$6=g3(pMg51&XBLdM8(GzOdT_81fYu@Tgk;uNGPefL8Y6Hm;n=%VB
zMefu^4Q?DMGF*z57Uz;zB3i_VSP|!Ar9>++N~{v+%SwyZVzgK-&UY+K4e?jW|E7
ztY|C7inZcAmU5z<7$??=^Uz8_Vw7HrL_<$2Wt6f?Ilq`#Yh|>uS~<^yvNp;XWsP#4
z7Tww^W0kead6o=or;Jn9Dd$Ne0@l!k7ev_1DzE`#ns(|Wct&fhwet#DOl*v{MmsMU
z9+ZvM)@tYVLyK2aLyQti?;r!!7K=4-7yt5+My1tf2`nh_D%GumNM5cIqT}
z&fg3xQOIIq=TFG}IXD;Qq}-6BaV5^e9WWlJu@*0}1C|Wq2L_-RiI4^h*3g6(MA!^8
z*nlxjJ9QE~{_g(E`<52E%i@%(6@@E3k$?G;Kv6?4|A;ZcoXp}KUmmUe8hDyK#^%p^
zI;pKMl(J`M+{ZbSpVzequawL^8S`M;&$iWRGrFa-XG(ly^^1M`b1n_MD(q=)C@$Dm
zs+#H>;@0iln-$v9Qn2*&tS8&w1j_2OBX>V~6BDXFa%*0D_r2_r>z%EoFY6zkKe1*;
z(Zte$){c&tW4b0j;YL@5PPQuc05UQh3*
z`_Folm%L6)T9E%EY1oJAlUGM9yxjFTw(aAhiox`RxHILClg9nJof;L0tvJ+prnbCt
e*ZqgngYz@S9Z#VHk=h|Qx_FzpO#wE82yM;+{(=SH6rm}TRu_as#42IwqBH;l`e8+
zZ`!oG&XaT8q(QwK(6cjA$dqh&AH;u(G19
z7%SF_^H|D>c4C}ZC(c7F0f|w1DH63jt&~y9D&_oQVy%_Y%4+3256apoW0W<@d0KR9
ztBh6FD(6`;terAWS*M&QjR;sn6J8KuGpoP`jA`1bli(Sxt=7&fWHGTZ+8XV=V0chA
zR$Hr`*AFeajnmd?=k35P?7786@*
zoOc$%@Stp+ao%Xo!W}Rkr?D0eTZ3wOYHoW@$b#12?8j2{?)VkANuELcMmUJzk3&|m|`
zH0{($@c6s?FYoQ>2iI7fvNkt+sweUI&z1o#FbbLG@
zS0y~N!PL`*+0R?e-Mzl}UiYXeD}Ii>+pXWroW^QZ*k$vu*tCV=N$+FFCq25DICkcQ
zzQ4~edvm>JdrZ>${OWg$e@uUVc5C3z@{b#0X1tp<=iJejht@B
zSKTXGT-B#3F7C;Z>2pN*^{BbSN8i
z;^gO6_lGP!wk_enmq=;yh!=-uWqz-!e0qD*{fyA40b3q4C(hr0>uyc(b!qLBI|n7Q
vyr5!mL0!|+;?+qXI`ueN{^{7ShI7pl+E_9qrKmEc<-XxicJR`;d0YPie}x|z
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_5.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_5.png
new file mode 100644
index 0000000000000000000000000000000000000000..2fec709cdf1d8ff14825c8707bc6365eff86163e
GIT binary patch
literal 1260
zcmc(e{Yw>A7{{NBieBp?Wgv|T0vD`eW@qALN@&;St?r$9?+?`vqxEvK3A0Sfl90x*
zSJt(lbtr2_udWwLY*Y?{+1lMsQO!j~v|b>Lh>R>+1*ebaKiE$@aPQ@L`##_A_t8z&
zvCl)G(LEagNyF;1)#=b@E=#3;QKiH4q5$|z-(a(*$f*2-vQ
zwQ`;ZWo?u(${OW7ExNT;#wu%-^DG(GP8p}HQ_hn{1gxP6FNm<2RbT_gH0{($@Ql`0
zYv&cRnAjL?jdorzJSZEht<}!!hZfz&Y3sD}cHkEF;0Fev7>Q^?1gxP6FNm-iXs`ie
zns(|Wc-9!_twbS^gv%36
zw||MJ+IpvCHO`E+=A{O=EPiuvan;gfa!Kl^6;Bt{nTflXb(hRvzUS}ncO;wEzUVG{
z@}z%5!!8HAn9}r)=CrQ;bv@C|8J*92
zZqycsTTUPQbZcL*vn)AS+Y&r^>sdzk>)z%OEy4SvDgtN6pBXnjIySksF#Iw%aV|YR
z*#&|XSw9xHS3mC?Xgf80PQ0M@vwNYUU$d8Ood0n~?jQYKudXc|eWCv1zj@n_bSB=$
zY96iouA`_fJ}ED9^HRgj*1lEii^gA16hEGrx>B$+f77giJ7ccBej1rKa#7>;w$Rb&
zbo1wLt%=n=R~N=A=e(Iw-#cdN?a~F?>e>#KTsS;4H#OnIvkf;cM_Z3?Eo%Sz{KKC=
bYU;`vH+bNmS!X0~=;o2iSolQ6f^XjgR>vr8
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_A.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_A.png
new file mode 100644
index 0000000000000000000000000000000000000000..837cae5404400e1ea3fdce416ecc62dbea8e02e7
GIT binary patch
literal 1391
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtRM>z^_bpI}
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!@p{nXRNF{I*FZ*cdf#R@#EUr$+t8JUE;>cJ-2OIu1;ioq{^ATZQkBMF5A$Q^84%#b{CglKXl<^I_G`W-mhOn
zmN_2z(-7l+V&gsK=?t9w3h^C|a|3i<@Sa%Tz@{O7XjO~DN%bVRvtA|ED~?Rqz;oxk->kez
zOW)?7H|XEBBJ1g)V3|u5bEY_ccsc7u`G;%loCZ0YqHesq(KK_m5OZFYs@T&-zq2`b
z&+RpTch!AYOzwKkZo3t;o<*M7C!KH8H>>{Xlv@gI3YYcgEIR${ti_4yO)cAw|9)`M
zTs}Be&0@pcs)Tg?`JX)a7f*`OShc+SyNvJQZ8xU`GVhsIaldL|;+1XlX7#@_v7G$(
zaA&V`#fs4T+35#YPhRrpl??Cw(+>qx_ysaJ*~+IVrrBOv&wY+L!GB3*@PV-3(&nO7
z)u&y9Jy*KKuJpU!)!}DjIdRd61%8jkrd+W5FFkMjl?^_9GGd`?j~}niH9X(GFZaHV
td*o%d^^>2y348ixuIkQx9N*@D6OUQ0U%WBZPYf9Q44$rjF6*2UngH*5|k%)r37@MeS!ki%Z$>FdgVnUPDtRPw_8BcFjn
zoCO|{#S9EwA3&JVX^qJYpdd@Sqpu?a!^VE@KZ&di49pAxJ|V77$xdF`UO~k{QN>YF
z)ltdS$;mCr*)7@GJ=w)Q#l=&KtEW`AOlfJE)6z4ir)O!;l%-RqterAv?VLGV=Pcd2
zbnV`?Tla3=dTi_7V|(|W+k5QXv18Ycox67K+`V(x?p?bF1kdk12ZHy{-vhz-_uqlw
z|M&l+U^D~n?b2tdH@)F3r&l*E{~6`X$`ZgV@lWqF
zU*p1anJtSJOp|SVy*V$WLb2+=NwMuJ+F|D}skqPG{_R3W)ZPmoi{`lM)qlRZdPm&3
zpw`A`S0^)^4Gh%0r=Y*~ht(6u98TwgZ<2>B&2@ObR%-+>7db3B{#L{FL~8fNOB>!O
zc1FCLn_S-F(dD`SySzuWxKU7SlzidKhx2{*tQXzo{ZVw4?YHvjljKh+mpDdoTzu?k
z)?VRc&vjAgsO)vYRX$ATziexb>Utd!#M<>+P-~OY-Ai3~&(QVx}cb}H-8rIVJ6Ybij%hl`5yO8;nE2!;H*d7U=FJ<$7
z{IHm3u&GqhYO1aOO@o-#!R`V3K04es)p##v{L1izu}2}(*Wl(wn`>Sc>=a+GU})@n
zJv{N1VZf(fEJno#if6A?^?A2-?WrWE)3zPE?se>%(elLa`-)hDqtVQ*oqhRVk0=#R
zo^1DW5mRt_w8XkCz0-bV-O09?`C|1=k)Qbzd3*QHdYS(FZvW@{Z`}MpEHCf8sVxIc
OLJXd+elF{r5}E*VSqb$3
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_C.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_C.png
new file mode 100644
index 0000000000000000000000000000000000000000..17e14859536adb765d73eac386f77aa9eaf8d072
GIT binary patch
literal 1271
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtRNit=;xV8Q
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M+HJJ-|2F{I+w+K}x2CIf*dOXHd~u8B=F
zS-L*;|9|^EQ@Q6&3HI6Z^McQ`mnG%5RXyt#I9}{h{+?;Xe&EQj_6$AA^OJwCvs89I
z;QT~cTF)(M@B6&xs$Ty0|70fRnQxR@)mhZtaZ>umTtW6rZ5Mo_4MQe+Bn!VUUe)I;
zd!yA>J%6#@qoUd#qnoS_)Avq(kp0A|KyT@ZP@2zpXo;8gg`ami
z6gQmM?X+1VT~ezsu#{JkZz<#UZm~sTt}4b17e0SmQeQneE>e>g_s9=ZPxYx7<+!T+PW*7TYlYTJ%T;Hy1Jz#cS+II)=Zf`HtXS@H
zZ96$Hi~C~hL$m*KFN$RTMlAU2J!k6NMV3>VIUir$aaj1U$>|&4HY~RcK5Ks_rzd|;
XmCBnbGx|(`vB2Qz>gTe~DWM4f@(ryM
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_D.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_D.png
new file mode 100644
index 0000000000000000000000000000000000000000..886a380d6e6e3ed89be559ede0324cad7d737255
GIT binary patch
literal 1420
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtRHb8k$0MK+
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M*?1|}v?7srr_TXRFY^Ij|PuzH;e(2o{B
zI4QN`Q_-LQ^%Zl&XXotQbxB8b=kfMr>FC59LkGX*=@b2q3(ftwt1Y6t<hw=bU@lB^C^Y(DFJGTh|d
ziX-Q0WwZAyXG*QG)+l_dHEqjm=5mwoE53K^Nj!i
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_E.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_E.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcbea3fb802f47e213f1fbbbc00e985169c0b008
GIT binary patch
literal 1363
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtRP!6#mw2EM
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M+H`=qCfV@SoVxgp(os||Qqqofp1OBxaJ=)#okM+&-H3Gci&fohbDz@C|fMnjErn`TWCkTI@x_ZGI>%!Qz
zdF&ipWEHn@FIk{pw(Rl_XRll8C0pXwTsZsSfTj4Oe{&ga_(Ep*8*|Ep9F1RdZ$+ErDL;fU#?fJ>!y*cc66=TW;`is^tKb*0J?duz}r%XK@
zV(p@@E_!SAz0ub;VcGb6Q~dTsW$p_$Zkj*Xm%Ma7w=ZWTub_82V=`~Gp$axK-ns@ktF
zzb*)7oSS-dC7TNbt1p8mYRak83jq<-qff|I{bZ)A8nfn9y!VwOx6QBh;zgpvHNx`I=lOw!_{9cZhwsUoEDcJuJqBgl{MS2E9q)~$<~v`_Ip)yEFODI
z%RIGxQpg#X36AX2pBw^beQCJo?;Cp2cj4o_*uyM;mq@&q_`P(S`)~fWCHj8#`_@DN
PW0=9y)z4*}Q$iB}AEMFJ
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_F.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_F.png
new file mode 100644
index 0000000000000000000000000000000000000000..506a3c50f9cb5924deba065b3fcb6e4cb2af23d4
GIT binary patch
literal 1270
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtR9`+dFbgQe
zS>O>_%)r3)0fZTy)|kuy3bLd-`Z_W&Z0zU$lgP@zz|0Wf6XNQW?Btd06;vD)RU8#n
z9hF?2oZOO}-IAT%lU>|XTs)qv+m0sJ=yqg@b{nU?3p}#IKigE!pbtuA1_iC3cY=$
zGA(X)wO5i`SKyi{2aEr*eB3erUhfL)K`+5|1l(Z)}4J(t*Tve4)+5)rWE{gQnlIc_BGz@yv?dxc6MzI3R$NfGPAB+
zzjE4NvDm}ApQU%QERhg8GC`d4-l58nRkIW}sp;Ft_$kHwNz(lB?B2}%ij~y@QH82Y
z&64NueP#RM&6I@y#Y<|%7Ty)u>##ubM_a}soAnSbQ{|5g7VG8gSp
VuFET$3M$ALJYD@<);T3K0RT-wslfmM
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_G.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_G.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff73d7f0b2e0c45c5d3ffe7e92fde1e92bcedb5b
GIT binary patch
literal 1368
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtjH}+~+B={S
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M+H`<$nXV@SoVt--ga-B#c^V$t#|;J6<9
zbRm07_7cXo)(y-CYAS&N|
z`NDT^tDc%9JA8b#ykq0dWr=J(JFV;*KZmo+-9PpDU75qNC5K<_4Zd%3WcBaf2`0ar
zOpOC|5~AcjBreSCo~dyvR^m~__K2p1d&8YI@-)wTl-IoO)YxAcb78Lwcin|gA4IF_
zHy=KE=qBI0lj~P+J+djIZhs)B;SKrE)lsiE-FvHb>EjmV5}%asybEuYsyRn&z4}e-
zFAK-?>QnDuVhxEVQF!f=r;<>Q%g=le)3rBjYyfn#tRYw!`^GvkraEt(fB$
z(_zqHmDf=G@>KC6kts^nXC#`d7&ZNGy6xR}UFMhE1p(IIAzKWWm02`p&YyVQl5hPc
z@5kB`TldU9==0d1-GSrd7VRCsGi%p*EQ$EP|C0Fkg?U*r4{b8#4Jr)o*3VmJe@lPT
XTD?211^NcSXlC$q^>bP0l+XkK86oH?
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_H.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_H.png
new file mode 100644
index 0000000000000000000000000000000000000000..61e95d2b8a0e0dd29e70a0deba0e4122530f835d
GIT binary patch
literal 1310
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtjGtdkDG?~d
zS>O>_%)r3)0fZTy)|kuy3bLd-`Z_W&Z0zU$lgP@zz|0Wf6XNQW?Btd06;vD)RU8#n
z9hF?2oZOO}-IAT%lU>|XTs)^`+bbry*BoKz>{;uU6X)hvc;v^O=)?OqmHIl#6}sB(`y9?~VxV@6
zHPm^|S8geu^mjWJ%$)GY@}o#{d+;x*i|f+)Z|vFhBzmiBgTl{)ypas6p2VK8G@bbQ
zT$cM|u~ivQdf$9w^N-F@nENMX`I$+p>#gjR-fs_+Rm@#dH92|(?~H=}H14Y&NmHl0
zUYU34(7a{RV)1|GHoqOetA>rU9ZaSZ3{j5@RBvl#OF@U7nf#L@}-on
z6MvnQzfi-2DQUX%+~<2$(ogfPSLXaW^-Io#7|*Q4Wv6?WT|DNuPkFC0EBmXOS;rD@
zyq(JVYZ2EaJuX!)yNn_=rQX0DT6+5$91g~v+iThQ^_Z2owX5iD?N;+!i<$rJEwGF1
zZ&wOleIfE{oU!Ac^8p#Fmdt9|vsUcJI{mux{5k(Uesp&p00i_
I>zopr06KZRegFUf
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_I.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_I.png
new file mode 100644
index 0000000000000000000000000000000000000000..23cff08624ef81e2b17aa3183ddd74a3cc71dc05
GIT binary patch
literal 1296
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtOjugIP7f%=
zS>O>_%)r3)0fZTy)|kuy3bLd-`Z_W&Z0zU$lgP@zz|0Wf6XNQW?Btd06;vD)RU8#n
z9hF?2oZOO}-IAT%lU>|XTs)m%_wCON?N{$vtdY1qVdAyin|!YiHP+Wj3-0#kdacwDT9A~U
zdHcsC4&G`8r`IR*_WZxGHt3yBoa9H_MN1w>7anA-=2#iBe69T6z;@f{b9QQfBy45!
zY~0V3erT-=6%$LkK4+U=FaKfL4TZHI-QF*2@Mw|vyea!c
z&*V)ph1YiN-mByt&i_rcc8$)T2icClEw2>L3d%Jq`Ke~#TfUN!MTIrKsL(z8H}|5~
z<(Ey=&uFTagqweKW?=tVd+8r{1+%URuSssPx_a|`zw_r(=j6T=GgN%q5_E6-P2DM<
zf4LY3>b-v=C?3yUHRY3uNY8Tz!B}pFH7ifuePQ)f=Im$2$8+89&zl#&_UooUwe8RS
zVl~eC>#zE%IiadL@T|h3s*fGbeFyj0uV8DwdTK|pPLx%((K)G`*F)E6D~leUe{xap
w$pf!?Zk|k%)r37@MeS!ki%Z$>FdgVnUPDtOwD)7E?%Gz
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M+H+uqZ~F{I+w(MgSc%?dnijL&&)Rz9~e
z``~7?amv2`(sFs1=jKT6OgU+K@Jj#uY1<6S@|n3c7rjnTdE2!;+f_20@p-+52tXhU!%U}L2$(S71c)fPP%d|k%)r37@MeS!ki%Z$>FdgVnUPDtOxsxX*an~w
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M*?1}0ul7srr_TfHH?lNT%S@J2nIktcrr
z;H{-RPqm-@|9@DtWcBN>&&-Td6)G$Ds6;dzwYc+a>a=FNgZFGA_$o9DXZI^Gy!peN
zwrTU$6z&Q4K5Sf)vWV;Lyrl>C%)4LA;1C)7eD0DPY4zSG#AP<06BYO1pB}&wI!pX|
z`rOLKT}SkpW!8AEj4In3tkQM*Mw(iI$cKIR0wNEI1a6I9G)JxH*O{`I_Yw=Qb>vl4
z{XesAO+cc<)(XkH*A;>l*Zldw{dksq?5+OuFHU&(@|&!7R$LY|!B5^>&|}{_uM3k-
zYI;;mU43Jg+qs91yXsfTdtd#vN&Aw(MTNSKiVFGGyzhGI)!B<*mvxpU1$+-Sk`7>*
zIXmI-ZQ&Ol(=1EPcdgsrqA@-1uIw~*)8fWI%L;b9GrOuVEphYo*tM&k)%WHpESj#L
zaJ6#jIfZnNvk$q}9g9q9c+X}k&sccp*s&c?#9laxl>AS*^kQ;e*n!F~nnycUTwQuM
zD~oLom+T4d&2dgSC!f6+xH~>l|44$rjF6*2UngGMg|Ahbm
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_L.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_L.png
new file mode 100644
index 0000000000000000000000000000000000000000..8ae5113b6874a6610a413147ea74e68a18ff2931
GIT binary patch
literal 1252
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtOy9(VX(dpI
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!@p9p&lb7*cU-?xfdw%?3QJjcG0%T1qZl
z&VjRLKmJ~Sc#~
zuRRwH>&jCsUdnj&@s_pE-t}!|^l7@{cHr?^;iiJ9wdR`V`V8X!FI;W^GH9>N=k8hl
z5e}lyj)klW{n+$U%HUgT)bnZ<<51Sg-!ohfUePSL*(Y#yGSdrgwPQ?4=egA8E>rQ&
z6_N^^ert=c13@tS@`V{ppb0eSdD>SHK`=@O1TaS?83{1OOVB
Bn#uqG
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_M.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_M.png
new file mode 100644
index 0000000000000000000000000000000000000000..26ca8ffa5e050e2ef82b1cab8b7b5e7c76d93cd8
GIT binary patch
literal 1353
zcmc&zTThf%6y1o5PMrpWQ^n{scxeSYDjbZ8(8@T-AeT;NXj2ptje5Ma0u`pB5vYO~
z9*UO;a-uPoi)P{##zr3`r7Z^19%%~N2J5BqMKIAZQCig2-NpF_edw!;_5k!<`WT!>+hgl{^MBTX>brx3>i`{u8
zM3$$cPnh#uVk0icZcfckC2BkP#^3A55rvZ{D>n`If=Ci6B2C057J{T8B}fZmlNOSs
zBqd2pVpA;?NkvMLR>Y=RXp)+gCasALmSB=hib*rEfffWLw4xSCM59Lvp@h&vuo;Y4
zN};6CQn2BHv{XVVp_O1m3)NB!rG?gl4NEjj7K(*t!G<(MfHi1>7l>doMgbdO=tep6
zxWG|TYAM+$#9+iqNv$Ls!Qg?k(o$>5Mn7nwTCvnD+1LTMU=RF&0Zm~;Qg4pW
z5cw}ZWc4(L@FCV^xKeY=Zhz(b$v-xJLP=&}P1KFz9pc26RgYck4t56zHvYD-sG-NX
z=kD&4zy31&+v19jNPE$gfJO&ueC_ee$Klz2!h)yo^4dbjlSh
z`)uB{y>sVtUAv>BscT#3*2aRAt$~XAl=jJsZ(6hCoqG#1YrhEw`U~glxita*U!Km|
zga>!!_-RG2hClLgOzoreBby>Z)wk{p*B?FGka=anRqvS(*S5VA`{M^^>Nj6Il-#^)
zLG;ar_wrA+bY+#ghFYuMJ~tefl-v?>ue9gcVt4L$USHC?$Tkuc|D-#y|DNq)pvQ6R
zi`x%7FZ4Ptf4@F`d0lbzvE1#I-2?YG_}i;1QVJ{`F^|XmKFR*)aS?2v*?a%
f>@M$n@w}2=zwDhiYjya_(HANsEys1ixo+RTon2Dw
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_N.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_N.png
new file mode 100644
index 0000000000000000000000000000000000000000..bc3ef22649876c3cfd4f82df781ad3cf2b69cc0d
GIT binary patch
literal 1419
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtob!L&Hc_Au
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M*?1|~*N7srr_TXTb7_pMeCklW(r6J46Q
zcDhj40gLzl+qjirCWw6d);2>F(+?$9(PG(A>;dphv(f<
zdC_I1878}so2_0@?TCMd!(=aA{-y4l+%s)mdh&lvGF*0hQGZ(OQ>%BYuHF5&_U*Mr
z`o=!(N~?<^cyF;Ce#990$8Eb01Y+tdl%PkZaRW!&e
zZb~q!-p|$9v7E#9g`DRBtM~F&?h?Oi^7C97o9v>B%&$K+7kqxd%zN5or&&*LMwDFso%{a6&7Ke)
z;YSho=f7@RzsqMHN9nW>L!pZi4!T{wl9JUrDihCiY1%9}B>R|IXw_0q>6c_OJ^pXGo
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_O.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_O.png
new file mode 100644
index 0000000000000000000000000000000000000000..54c1923d2df3f90e80ecd81cabcfbdb9ffa6e1f6
GIT binary patch
literal 1412
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtoG;Nzc^goO
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!@p{mawEF{I+w+~C)fRx9wZZQazfw`fDu
zG)KK-d;Uwy1#Dcq`**Urv6r5_;uG!`ouCkbYrCNUI_1ZFlksvUdx?2ZGh;rK9;o59vY2$Tm&mLDf}G_C$|WNGc}X0M~>LY0jP
zx2jjW=WcASi)UQ8ec9IyJkmmQlFm-gk4!u6{yFnaf_3T2I_tv!j4v-5nfD~hoCPKc
N22WQ%mvv4FO#nk^>S_Q0
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_P.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_P.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7c1e00c5a413940f4703dd08f580846cd659f4f
GIT binary patch
literal 1371
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtT$stmKOZQ>
zS>O>_%)r3)0fZTy)|kuy3bLd-`Z_W&Z0zU$lgP@zz|0Wf6XNQW?Btd06;vD)RU8#n
z9hF?2oZOO}-IAT%lU>|XTs)l18Pj!$u
zA?TNU;M=1A{}12T(|5_o_;MM0isI={uNnooJ1o6+zwnh#RW`eE&)dQlPx{z_q!g2e=IM#K6*7;
z_UNyE$*j2Gn$wd9HQv+0-bw|$TlQ>{$=Mm#XNZR;C-~%j+WvNd?fn~z{`R&^eDq#1
zJ9y?_m5ka-rcxb*Cvo7bgvoHha7IvyR`wEJ&$XZ8TaPMtU4RA=E#|t?>pF2
zvTq1^XPx@$rt|VrRe<7^Bl~LA`S-2gnB!Q$*wZ`1?ZlC_mG9fPC-qix>_6Z0`s+=W
zdb8AX^Z2_qpRaGbqUL{f=L)0E*AidUM9=jUXv#jj^pjkH45Qq`Q}K5;MQF<`}?jNs0FMqaNeQ#~y3x5?m
z!_3$kp2f~D|_`LUgt=9_n9ev)Az>siR@RaJLdFf_Ro$Z%rB(XHA}B|)E`w(
Y4>z23J9E`6U`#W3y85}Sb4q9e0B{iDlK=n!
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Q.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Q.png
new file mode 100644
index 0000000000000000000000000000000000000000..9b84be3ca07e8b862968994a4ef7b96ad23f5a26
GIT binary patch
literal 1474
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtTw?0GY0rT|
zoCO|{#S9EwA3&JVX^qJYpdd@Sqpu?a!^VE@KZ&di49pAxJ|V77$xdF`UO~k{QN>YF
z)ltdS$;mCr*)7@GJ=w)Q#l=&KtEW`AOlfJE)6z4ir)O!;l%-RqterAv?VLGV=Pcd2
zbnV`?Tla3=dTi_7V|(|W+k5QXv18Ycox67K+`V(x?p?bF1kdk12ZHy{-vhz-_uqlw
z|M&l+U^D~org3^`BDm(%k+oC)aT_lp3*I>ot##+NGOvZHAELv81-bl{r1zC$RIR
z6n5WB@H+BoVR9b#kxjc+an<==Qg&Lf{w&|I#hzuU8}t_+OuuqGslDv>*5he&dM9|D
zW>~Jm>~KSKnmL!_Cyz(zJu!?5PnU2xAB~%E{Y`X=Yothc6L&hpmVGXo>;~s5T0SOl
z^)J+3ooI03?b`DTc5jJSJQux$_3AtOH&Gr(jMueB|GAiPE{b8d@7m+@W)#}2P&ACH
zH{k!Cp_frPsr%UDK$S|_8D?qMI2by+j2ab>`zWld{xsieQnzWxi@uAU_bRt6(aibm
zv4el^uh38Yd-iIE7k#ULaQ1zn_E;VqY=p5*Ht)mXXr;@M<-
zE%U~2HGyxZSL~VOxPIZ}-x=M%#R_*U%Uuzi{IoRrs!rg{^EbsOZJXIYol8sjd|dgD
zFHbh#iI;vPeDd`&XOAGU`R{$dOI+ADd=lFZM%v7D5Q)}_Gs&v6Qq1Tbs
z>uY~Iw}?7bXXS<_eouFhTC?=>%OjDCwlJ*To_6c$=_vQPf)9Re54@wce-U?H
zotM+qZ_XZZ3o8Tn$~Ts%ab6a640Wiec{_Xh(x7Xs>o4eCP8OT&5b?b2FYlb`Hw|Sj
f-~a#d!e2&r5xd9x_Ab-_CMX6^S3j3^P6|k%)r37@MeS!ki%Z$>FdgVnUPDtT=r>8QU*|n
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!>`1CxxWi(^Q|t*IfM>lPdElqlqiZ4^18
ztoyb*sL0~qfBTsB)z`Da&vR&7e9N%$V~9Aj+`2lJ?OW{n8{7ZrTnl8{z`)jG@Q3pO
zgA41@8QXg@zp$wMAC&tm>R~9tSp8Hr)4anZRULId#VxpUPH)PscVX9eO>7o%h$$
zru&(3$8LD4(67v&Heq%N?z5J%%q9=FHic?Gdn@Y0irKRa;t>ufJ4G*xKS_RB){0
zg`e~^*Ryd^&$rxq7=A_UvG1PGD<80{^_*i^6A8X!@eEY#`
zrj5HUquht%jFCANA5K|)zjoPg>ci)8>t}qKHZ?4yeYTDv%0pfLF8sW|
zv~|_b_|`W{KO3txyP98FKdw9^Z+eQYXxqM@6Z#{rDc@LWzweo>`@Ldep+~t!ljV5W
zc;cq(dnl_(U!3-s)s*0#ps
zQj2RRig$%YC-1HM|k%)r37@MeS!ki%Z$>FdgVnUPDt+{&TvI#7mz
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!@p{oK>VF{I+w)Zp&C)doDRA3OwIbL2E7
zdzlmq|NO77@Ri@Pq4et3RS)Lfu&X=bStPn^&R3U{T6bet&U*UCpz3GBq>j^P6V;p!
zb~$DrIjp<4CBWo|g^F~cM~0Z{yi3v|Y?tG|eo1Nkkhpu(e0@EO>_cy6Ejcys#sR(;
zcDH`le~?T6!F2haqOaZEXA@JnWDCDp%*rYc4byAMVOLY0Ia_UiqkmxJlFz)Sa$Qu6
z#J<_QSDAWi;qPnO@wcj@R4gKzi!V>PwBg$1D;Cx}7iuw;?Y_`-J7MeP4Y2`jXhE%5}?z9APhs>(cITTqdouL*e!;j~naHvfBuU
z=PA^$Vwm#k$h^0u`q>sTA^#&q7yY=plId;Qv$RDwT;)qP8=tn9+PD0vdH)MT1;1tY
zB$hsy<34L+P=Mawq;*N|>LK!#D+2z0mFl{t_-o&(V$GiwiC3lUTP+JNNwCj*p5o9Y
zpSXGP#%s~r9v+$QIq7g^le}Z_!IYpA&bLcq`@KVEDE@T5;aoYZU`qb1`{(Q)eMk#C
zdSFiNUhjQ1b*Ccl&9j~NCQaK_mgBI>>7Z@AJbmU)i|*&o-Zs7W*iuG4tGeg^K2Mi3
vVa{i5)7V<*{<2!{4;pE`njxgN@xNAR1W7d
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_T.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_T.png
new file mode 100644
index 0000000000000000000000000000000000000000..fbc00e6057b95d14a860df0e171e96d7b7ae4983
GIT binary patch
literal 1284
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtg6&1+c5k2%
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDc_PnX+`sl(kdlterDw>zt)qm#*Er
zcI)1)TaRtsdu;FCb9;}SJ9g~av2)kXox6AL+P!P{fZ+MP=RolO`FkMv{{A}<{Qv%c
z6pV(zpb3FCuQ`W-d4sVe$S;_|;n|HeAiK)b#WAGf*3{s)Ma>EVEQ{|Ms7ZBkn(}BB
z-1}{xbg^ff>RP{V$1AtLD~LaELzp*8*1nGOL;Kvsxt(F>^0pOuZ4b&^JAHw|#rT^iC>
z;is`cK}hS`Jh{^4AA-D(-JJcvExLMj$X$)asqtrd1tYB$AGw&g)h}yd&1H8=Z@(Az
zwfvBxLs3%ZFC|&QUpfm#zUuQX^j%{dph~tEWKOgToZpSD?
zw%6{nz7&hvuqPNQcYOM^@NmnriN4H+i4(&g^?L`FOy-W=c>l0#phKyGP}@7_-Rl#-
zPu#HkO?J`K|k%)r37@MeS!ki%Z$>FdgVnUPDtg6rY=-w8k=
z&H|6fVg?4T4?0v(btiIVPik{pF~y$24;o;pAc84WGAm|ub|?fsN$%o
z>Zs)E}?}6a^`|m*T
z|NH+@Fd71bBLtooSy=(|24hK(UoeBivm0qZ_H|De$B>F!OM~C`EjHjWk#Fr4U{6h4
zsOiPr`S^SNVdKUnkO`J7+rFSc_~o#_94NmA>w*WX@d^h}s=Hg1PY#;qreDjsojFKA%u^P(8!hr~
zn6-HNu@kFK*uP>m+~hXv&-F(#zOnDvZ?E0GOl9`E-)@`RZ@owid3C}uNHc|fqVAeS
z+t$4Ll{#bDyYzYgl2ar*zVXhxmOJ;@b%`}|j&>@m&8y=pGryHouNEt!ZQ>Yby_q}y
zr1s0leM?deqIG9-l
zwjU}}PrtY`XP(FWwyUi(^|*Gv|8VMLwC@(T>Dw3n*uL&x*}`a(g*9;#&i7rg(!ITH
z<*h|0X2#jeDA#BCWu465utD@rap~PvybpWp_WqhQW&Y(q5xtJb@8zZ3e*VE%MbpIh
g@>gHR|DyXDH(u9Cz9Gzopr00L>}F8}}l
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_V.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_V.png
new file mode 100644
index 0000000000000000000000000000000000000000..dea84433a39ca34de87aa09ea711d8b7c3a904ff
GIT binary patch
literal 1322
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtLO^CMlN3;h
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxzDyLax|y=(V?;Q77hK=A(gdm#A!{yPx-
z|NegzjE2DA2!ZECR#w2g!B`UH7tG-B>_!@py};AOF{I+w-oT5KmMHM>JUSWKcTTKz
z`RRy^h7X?s6Vr+j~r`?dgf1LY&|7`5cbPU*J(U=uwQm
zsdQj{-f6E(1+1G{s+c73x1#rnsH>bC7d(liag^H^SI;;+LlI{9|<4Ti#Zt>$%QL
zv$f84cY;u->egbZ8}i*Yp5d>T-tsm{jOw;4o7`H=y~GJ+qIvYZ
z^d3fYIGg!wkNRnFT1Ibz|k%)r37@MeS!ki%Z$>FdgVnUPDtLb|*D_9UPX
zXMsm#F#`kF2M}g-T4OQ;D9DoT=P
zbyRY7a&k*@c1w14Pj+!naq*Pm>M7MNQ(9W)wDipB=~>z{W$BbDYp2XvJ7><;IZL-L
zUAuSf*1cP|9^1P2*xtS8_8vQT?AWzq=dPVQckkS_d)Mv(!Sj31f#Ch~_dxLd{dXYv
z|NZ|c7!85J5dzPPtgL`}gRvyYFPOpM*^M*?1|~627srr_TWf=FPFifhGv#ckNa6_r
z;RBD0Y81ZwuivpPQDO7RJvnRTf_B`U6s61lfP?7+gOEe?M23y=34b&j(iw{+BF|1V
zVZIUlXN7@bzSxB0F+x8dJv5DA{o8h1?JLhhXSS&an8dU*7py9L*sUM5==>x$mhBUl
zbKTf|XyuPPHglsw7U24
zIP1VS0c|2j&9?BR=kI&@@Wc6wXAbtSNEw#SAT-%`^=Tvd#_2GM8q$i
zu=9RrxK&v&ms>uB{2oB
z5DS|#m3?P~eM?)oyW&2UW*-Tse;=>dO=teP?d*{Y*;NZZ2@8v-F8%YcXzeu7+?}DWfg3&_Y5%o-`$w~X42mN9r&L?^Y5|iAgQu&X%Q~loCICKw`NaSL
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_X.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_X.png
new file mode 100644
index 0000000000000000000000000000000000000000..29dff7c73d973e2d6980c14c0566d51b9f91a475
GIT binary patch
literal 1397
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDtLeaOFNdYLt
zS>O>_%)r3)0fZTy)|kuy3bLd-`Z_W&Z0zU$lgP@zz|0Wf6XNQW?Btd06;vD)RU8#n
z9hF?2oZOO}-IAT%lU>|XTs)m7jvc#p?A*0;=kA@mcJJCfAb5W7IS{;m{vHUvzyA&d|G)nq
z1*0J_XhPuYRQGyd-e4>V@(X5gcy=QV$bRkV;uunKt2MZDQnLb&@0P2H7k2e^1hsL^
z`1F7Nj*76|ckkXvyyV_Dow>nPqb~4D$rFp0<_vtZ4H$CNjN23vetoRl?-CwX6*#+k
z-uVeCOjxVPLUbn^k@H&4_=LDAjC<_=Mkk*Uj=c^LI6$
zqDA}pNip>b*Yb~@44XCa>>WH_RbXudGht<#A^0KpPRG)fB7i?{#f|guC9~2WzS?yzvQeVIJtLC^}4+*
zd+dG8E^bN6uZ)^mwQQce#`Wh1|LR&^ne#V!@|DH>dX}@7#!OLH$eyzO+{d{wHKJu2
ze{ZX$Ev;_bo3v&I|3Q=YQzmLYJ(KWga?_hBay6
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Y.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Y.png
new file mode 100644
index 0000000000000000000000000000000000000000..9e8a7328a11f3a1010c57637dc35090f32d66428
GIT binary patch
literal 1318
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k%)r37@MeS!ki%Z$>FdgVnUPDt!sz5#=YK#U
z&H|6fVg?4T4?0v(btiIVPik{pF~y$24;o;pAc84WGAm|ub|?fsN$%o
z>Zs)E}?}6a^`|m*T
z|NH+@Fd71bBLtooSy=(|24hK(UoeBivm0qZ_8dF!ts&W)S1a(eJbGbp?UzKx
z-YFXu-aP#O|M2T-k@G8mPB^fs^W-8SquI(?JZ*jVCSP5CSxcIKs%mxfj30}=c{Beq
zwI?Z`XJz0{@uKAd3KQe`jncJ~GKCkf>xDx0bc3{~dzDjvI;SKi(4*(`fZ{eM#=
z`=W1#M_sD-DuhlreMdHJ;g0v8TlLpUK2Lk`BP=9q@}wut=htbr@?U**q5fTBV-5er
zQ>-#eB+sxrE1!t)OX5&J;e2F*tE97Dh~bi}E5jCkvz|3ISJqrKdTQy5b5l8lyF_2h
zUW`#R(X+p2r>ncGHc#oy@seFP3NNMeJIG)9wEg2Y@!P3krZznt*0mMvTRz`Dzf_*(
z+H55$Gx7P;_n;d+6biUl*;AQol7xyF{`Vf-+L;P;UZ+!;8I`M5~
z_6zg%pR8~5Kh^bKM#+R}od<8z%URq(oV@X|6W*~+_|tS`tNGQxO(y?JZ*czMZ}C%j
Uw}Dk71Q=-yp00i_>zopr0JLkvcmMzZ
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Z.png b/trunk/apps/showcase/src/main/webapp/hangman/images/Chalkboard_Z.png
new file mode 100644
index 0000000000000000000000000000000000000000..04b3e33d74e0e1795cee3fc0d21556965142deb8
GIT binary patch
literal 1353
zcmc&!=}Xj66upD3#%PNl$}ED4(u~Yk*kY8^OgfF4A
zt+Y@Gm2IejSejYJE6p%eVk%>3rBbqzjMwq~2Yu?nZ-)Esz2}~D?r)|bDKXaQAM8&=
zMr)jT3BJemJ_G!S4Ch*xMI-2+Wlga3e{S#}GH`Zwq5BoC24=)9&m{8y*83PtSEhMz
z*~b}^5JPmMXi(4EzC?bM6mPfSo)K{(K_rQkju|7)NHCI&luk2FoRi=rIVoMu1aUz^
zkQAhJGn2$62}x3t(pXFpS0ofkMM^_60uowLizK4n!x!vJ
zm=H_~rZg>7bIF8cQZl7kqM0iu6qAZ6O&TJ=8Z^NRL@*hnfDJHoqa1l$;0Vqo=SnNY
zV8lXjDY(*t!2@X_xs+UK{h);cBZX;=#{VIJIqJ@5ktKrtkOG_b%L
zG{Fl*Fd5Lm1{k_gjyx`Kl-?PvghC8Ptn>=8e=Hmu#!9h6EDc-2TCfKg52s-*yo4QK
ziDvi#1E3fZK^j9a0`PYvz8<#Ya;*hLB=G{
zSNsqQt>zfJtL>1z`bcfW0Gn;v{e#?9GGg_n{A~dub-gn)>S1bRfIF@Jbx6$&^OH}L
zt8X;KJ0gCoeVI+|N2mWfkfu7_XN|K$t{=PW*E)MmsAbBX;Y+s9qSVI5r+t`DX6OM^0=$$QbUIkB$7&N<(2r&NWGy~d?GCV^XQG?o*$m>8B-b)x(&OsFZhDe%P0tefg<
z$~s-%Sys6>ye!~j&CS~P=i?iLLRKy|k%)r37@MeS!ki%Z$>FdgVnUPDtl0`n}xf)Q2
zv%n*=n1O-o0|+xZtudJa6l6(v^mSxl*x1kgCy|wbftew|C&bk$*~u&0E2uaqsyHgD
zIx4w3Ik_b{yCpljC%d?(xOhr&^_1$CDJ?B?T6*U6^epX}vUJLnwNvJ-oik_aoTXcr
zuHCzK>)x$fk8Rz1Z13K4dykzvcI?`*bJxyYyLas#5In#490=Y&e-8xT-+u>!|KI%W8HnSqnv0Qa=rtp$Qu6fJ;
zoqqbe{z&EG{3x@ih(z5t-<_Tqswh^5yi(tz`r{j;Oh{?-;ZKewJiDU{zaKj3=476?
znO`KhF62>s@Di@g92ZY{bJyQJx0!kC)$bb*N-)ooG(Xw*^68!MiF%tZ)m=_Yzbn+_
zE0Pt+zxks5dNu{A{5@tIQO)xl4lh~%ry+I5^COq4vu~f&EwneB9&wuK`Gf5DN2s`l-(S8IRx3`kQ)e?mQEQ6@h{URua;C4)3o1$MRy5;4}g0t0#f}V(@hJb6Mw<
G&;$U$m0QyQ
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/choose.png b/trunk/apps/showcase/src/main/webapp/hangman/images/choose.png
new file mode 100644
index 0000000000000000000000000000000000000000..f445bebf39dab8cc365ac0dc2e297a10bcf7cb30
GIT binary patch
literal 3321
zcmVWdKuQbRaY!N?~pwGB7YRATlvJGC4XjHXto9H83zp7|;m-000McNliru
z(*X()ISdiEZxjFk010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00RI}
zOjJeE+S0hhxQw8TMQ24wYDjK~Zhn@2uDY(Kwx+1KsF0+PXoP4;X-IF1Z-knJhMb0Y
zka$#dRC0@Qma3MlysWgqw3MinqOzixsFsH(cEnyi|mwxfuih_u4Aj-rmDw4$J}
zphjp$Vt--0Yf4gbQh1VhilB;+qmW*FUXrMiq_(7e
zmVJPjfMbATp0b{Yo`-ghc5R4lWPoH{d|gXyOI&(fe3X1mZcVPduCl_ivcR&o!M3cr
ztWR)HzRbR+xTdbYuCTzcvc0mt%D#J)d!V$Sg`9<=v7&U2bgH+iufVUi#V3ig2d0re=a>UVC1I&=-v&PWI&eqPv(8RpPyqv3?T6kKFq>QY-tZIg8
zn68+zzOr(Ra&(P!r@E)O$hf$|xV*)@yvn@3$iBhQ!N}6c$kfQh&cwRNx{{=lf0%z(
zbXLI1z*~A-%+}1x)XLD<(8$opPHs+?td?klXnd1=#?HpV%EG$Cy4Kv*%+$<-mxHvw
zv}%NEz0AGR+|th2&eYn}*x=Z}$-u_a#=6A1%GS!#*V4qz#KO?Rz|O$j;@s5S)X>(@
z%+t(Scv*gxe%RjF&f3n((#qJ}*v{0>*5208+R)nI+T`fu-sIlW*wV+;$JE)>%-GD}
zgMU~>E`I>-r?Tu@$KmA=+4v5P;XFWf@NHJTmS$700010w1`{)000DZ
zQchF<|Nj6$Dyj4U00}ioL_t(|+Fey^a2w?nUG6d1Jkt({
zNfq9US1jBtjxO(mJKkytF5r`)>6Dbwv=4KvLXOL!G
z_aKNCC!GBdMYP6Y$qe?r4VUqj0_Y0#{TNQcE5hqzy->px{{^KcGE5NX!=79Vs`3WF*W;#2^5TDPGCXX#9
zqF`$b!yF6|q8o6jt;c~wgmxyie-CDW$Rvrj)CorqxP4e$eGp#uI{sAz|L}0tbsZvt
zVTd{qORjr}oZ8r7Az`qCv_k4qa7%nJNU};|n~fXu774t5lp#ky
z#k7qP7q6lM+mA$}eUv(LqeEt?`)y(Jl{}W|28^jFVWz8d0)c{)mIX$Q+r&=i&VP=~
z--;9FQMS@aJNYH41kwd^>cV4;Q#MqQ;tR>=L?XBgj~d1#X-UM?X}Va-%Azov&C<-H
zMM9@=F3$Wbdp=M2p;RbhRILOqtzyvWb@c;sJ&E|sknSL;qtn#_)KqmfE(Qcm=>s<)
zTZF!TXiCF|=jcCkllu5(JQ9sF^iC_3`4IaRWf=k7^prwh}G1
zKYWe)ec#uErt0p80Z*HcJ&4!+b+nYiehzI4tFjz+DzpLX1BAfh4i8o|vOfR9|4TdM
ztA%HI#ctz?5V^A16MhRg@E%dik2qoBM{xVzT(M(Anb_JMwh7q#V;;*n&Y^W995z0Y
zAIE`^W26R#ED*{E^hDB$Nqd$^VAQa5TswYLT!`;Y^MZkE^kkp8kH&h|rSxwkRSJ`-
zJQR_m1dGSLj5jY(uQ$jk$SWX&C>>Si7
z^C)p(j&n)iSyi{1F?lMilUNOjh+s!^Nt?8?@oZuA;`z*J`;yAMUp{V5%@(oz05ZiY
zG|w_Fv3>SRfy|)c6#Puwr|m>4Wq&{i$eOTx`8=JT3%S`e
z7_*{^i;SWCoyrnKrx?lzk?X+i_p_T|Nxbk!8b6vzCh`{;s-t9nG>_NP<|V6OkH$-+
z8l_7qd~TIv1x%)qQ^~o|-)fMN;v{Dw=qS|J6nWVnjPTUhI8o8&DhYJ-CBB`gOzZU!caL)DXKd
z<~fW3#k&{RIP_%%*wU#vvDA*(MDm9tlC=RoKhf$+{wJuVl5DANWPi2;cl@+xXL3N
zuLJ-$U*FaGw!_yblNGeef3)4ZWtm6j9lxRePsm>0>Gb=6O-it%*VR3*gH?vbMZ^f{
z>p@u!4~;l0@bgn)O*dsKig?@-dtLH1#BPo|#L2d>_d~#`bjIV6x{zEeEuIfWcx~mR
z`(uZ^+;^xmziUyrWi7G%LR5}4pHhaYt|e($krdf#iIBU;qDEL%gsDba?~%Xox-Lfd
zP*wv;of$hj&D=tF$8>f=W3-J_Nm|lKXSDHhzJs>SXvxDUSR0h~Tg!qoszUnwhzw{9rIKd1%`G
z?oMnPKQ=TnQEH#sP4U$6bLTIsh12Vxk51%AKTb0$_OhV6;=QpC^*>SNwDW###A`|3
z${!MprSm5yC-JG>Z%RZ)x%s!}KPKk13|*n*;!RyE&J}Yr*;HN~i==bwDVm);d9GMY
zk$sn&JNS*NF!xCDBbwuAysz@QQFbLdcTwwoL+Rcm%*4KSLP_*6Bd;hW
z@S)BaHTzgrllJQ7&8V&g-%-Tla;
z<^Hmp=i!DXzReZn7Z9_tJyg@m3hw(|Tgze!JdOVWbAGV(l1t%P00000NkvXXu0mjf
DztrBi
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/guess.png b/trunk/apps/showcase/src/main/webapp/hangman/images/guess.png
new file mode 100644
index 0000000000000000000000000000000000000000..011978e7d98a501989d95f4e5e80d971e65e8b12
GIT binary patch
literal 2900
zcmV-a3#;^rP)WdKuQbRaY!N?~pwGB7YRATlvJGB-LkI3O)BH83y?E0X>I000McNliru
z(*X()ITq~ImTmw5010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00RI}
zOjJd<#kkYk(?w@RjG>H3YDidjSdpZWiJpm(rje|?tf;uCxWl-Pq>e~wNK|xGoUELh
zteT##o}jXznyQ+nwx+JUuDZy&w#2reu%LUCdrWLha*T4Gu%5QUww9=tu)eT#jdYTw
zlBl+*q_(7#sFaYSkWz6{PHs+^teB#*qQ1($y2iSwx~Q_ivb4gqyvV$zxTU7Grlz>2
zs=BJKzOJ0EoWRMzoUojlu9~d6tfI7{xWu@2kanuLs;a!IlBSY|oQ8Iec4mTRZisGb
zg=%VsYG{OLV0~asZcSQvT9&Goik^y%pp9>eZ?C|wh@XgvoQQ&$f`6EQaEfqjhiq|-
zaa?*_N^441byit-S-{G`n5vk7n1D%YNxsIujGv6T#kr)kq@=Q>yvDpza#DVkevze-
zvc0mq!@IJ+vcAZ^xx~4Yrj($spt8cUd6Idcw4kW9sF4UrI5tT#KO$Nz|6qN&&Z0Pid1t{qOqd9%DiKMW30KXk*AS_nuNN<
zx~ICQu)wg!(8kKt%Ei*f&eqPv&cwaUyNz_yU4kgUF}w#K%`&c@W-)Xvz>%-GC$ka&Wcg1p7NjG~OHx2n|H
z)Y970(Av<<)6CG=(9YG)*51~@&cMgi$JE-?*x=aG+tPfLe7MNC*4)<6+|ZDuklNzf
z&f3n>*wWPA)Y#tGWrAhX+S6BdSFpUW+ThyK*3!_`(9+z}!_vc8c39oy-O$$1+2YyQ
z-PmV@XV&1>iJytw;oRHg+rrAi-{jw9fMnd_+~eru+TPmX=i%Pt-rncl!O+1*Xhw;k
ziD-jpgPenssFIwjoQ|Q6e3E>kwxWunifo8%hMR_2cv+vVp8x;=0000nWzv}d000AY
zQchF<{{Yv@4M6|^2a!ocK~#9!Wma8q6W0}9e-Nfx)5ccxlaQEgu`y^D?P9NNkohqU
z3<0MYQ<$M$hazKWMh>VmF`~l?b{jBGiFUP1r
zYoNdqjsQ3n_%*g~0z{5gS)7Fy1cm|Xule_32!ECoz=mTYK^BTOD+5@eZu=KfA3RQuxxB3}90tZ(nZ0<5fB7UZc=8!9
zK+8YqcYLG3=$7rwtStHHrKm~f5=;0IRY~xI;3^lv-3-qPme)OwtS|6|!Yy}RTufCe
zl{?eG{{AVGsFxMqIi{#jlHYPhMMJd~M@|z;rYf-fE@0{=^PXW==ZTTnD21un3OOs7
z5|;pSrj&DxoG01%nR3}7gJ6?ropvPkcRF(;d7)A}0@_tEgvi;>UY`T-^dfjX
zd!3Eq<{>osm?RfMudvw@0#?LU5%&^=1yQd->ggu~^-R}?w`Wb;I_&%9rsGR-q;K#E
zAK_}ccd8wDgI*6jwr!E4wP%22>cNp?H3!-UTi6$HFET_&(Z~j*4!{%Nki^z-+(+Z{
zO(MfDg4gHq5PAI*<9N%vl-F=JB08CAH-tOPrx7gOyXCwq@;=Pe1RPV
zH!PAc;Oj{e3yzgYu+bKF_s`v|-f%=#50Lg4HWF^AOp?jKxUAvGPVn+_RFWJs+5K~8
zEg&&=#p2!b?vGP<#1?DfivW~4(+%$iLOE=ydCV-h_|>FP98n9TO~GINw4xdIJ0-GW
zr6_YM>tv!uuj<6UWC?CPaVb)FrTaRm`5LhnXt<(tSL70qEgLpdDSyOm#i&H}%vUG(
z0q+*e#XEqiwz^rICT<9m-EMZuQ)isdU`u78NR^!FCBpXcXAK$W{H5XSybeT4<0(>>
z1yABGFl6=j0vTI&ik2=%4rA~+XP-&)DW_A(Xkax%b>q)+1_^D(-{{2id7e@*8V?b#
ze=DY2Nn*C|rsZ}7`6yY{1=8=~6~anVbvd2fLzTSKgiF~oh>xva>F^#IA4Ff0ED{rl#$r)c42SY+jU)NFJ+9eKA)3NcB9j`4T
zcgVr8=t)rngD!uU_-e=(9|e{~dN&;MQvE#-6He^^A)OEV=tw6`#2sU4l_|U=@GZco
zsHU_a!(D&fQT&{XQ=5m1{#8ytza4Diq)=Cl;*=`M)D4~#(OuTV#1bCnsEhkAwgp8e
z{SRUz!s^u6(&oC>EINZ-lKARI_a$PmdCe*O*
z%-VlXDU7C{uP?01aiSLAJ&!%&xA-^w`iXZK&H=ACuDdUD^S7sKn+NJ+@Zn|u9pO#M7C9_1!+;Hte
zrNUZXBY}z8y79<{LOi8hFsZT>OLLYMtX>Pp9QgWe+4x7PY^v2vVAlF)w>|Z-1J8e=
zG*GephsONvzsRfOUE3hNjM{e{^LwD~prK
z#++-%RxWENvq1a3siw+_E`Gjqv5>i{Ef7Q8g9jN-SKX
z*eOtr<$Q`lUh<0Nabm%F-`5`xuoAB_SXe?
z&NIx^Hb0XPN7DVyYe_{zOn)#Qb>WUqe(YDun@+W+@&a3b{}wO#8oiW!A8&r5+3yK1
zdFsoUJ>5dyEG%2zy7D2iI>b@IHsNW9Ei5*6Mb@q7dp0^so4b0qeEZpL+nrY4Nq^_D
yn*OrT?kD%`*}LzX`-$+qfcN`#p6_~Jz<&X^TxB+tF@N3w0000WdKuQbRaY!N?~pwGB7YRATlvJGC4XlI3O)BH83#VNTSmK000McNliru
z(*X()IUEcCe{cW*010qNS#tmY3h)2`3h)6!tTdPa000DMK}|sb0I`n?{9y$E00RI}
zOjJeF+tawkxQw8TMQ24)a#DPhe5<^x$kNEb%D}|V#E_$qP;gM7vY^b?%*N2h+ThyI
z*wED6)Vs>N%-GD<+}5(dvUHAgUVC1XsFT3Vz{1YLYKCfsoQ2fd)Rd@{lBJTv(8IjQ
zytcx&y2iS!x~!zLq)KZ_sJN)e)X28Pwz$T)#L&dF#I#3fN2t1}t-h_Vz^}N&xR|P#
zw8FHUuAHX0rkk#tZ;EeLbylRbq+@_%OKeNj-qfzVuBy7Kbc}RpglN*+(%9bE&eqP}
z=HA@m+|Jm}#?r>Q#kttv*uu=h%F@cp)XK=v$e*&GNNPyN&c?pVzOcTqaEfqOc2}LS
zoo$G1yvDrB*2zR=dt)7sO}
z+R)zO-g%OFx5l@=%)Zjt(q4RC!pg#Uka)Dfv{G?W(cIBba8J_Q(&Xsms<^7!;@V_@
zWX{#j%+t)=;M{tfI1_n5me9oP(vfrNqp{
z%+$={=HlSy;F6}2*5KCC+R}cNeukWehMtDpg0BgcDTs6*4x(N=;FZ6z}w{8*y7mY<>G#p
zetMF6T6kK<&Bj=ESnBTT;N;-u?B;5PYUt|dY=>;+?B!^KXz1+d;N##_b5v!5Wq_D~
z;OO9tqKw$w*i39pf|-Ka-r8q`XJ&$C>g?+4@auMvcFx+)?CtFC@9ymI?BwR;z{tSp
z?&$39>~4u}V0>V*zOvuw-{R`xu)wgcx~_Yad++k^)Y;VT@$R$4v#YnOjh~J1^6<*h
z%1CKQj-igw)zFrxmbAaLk*ASje`1E4hLx+8($>;^lYDxSdZMmJ;VY(pZ)=ew7I&n*7h|Huz??6II6K+%3TgDHrTzfd6VRTYX1
zx|kO#83}l!*5F|`65n!Udr>>%)TYV){bY}@iP))v{Bn4iLXPZXz$7uzM5n67(Iq0R
zXv7Z#BpViX0}e23t(inJP-9Bdp-*7Q_eKze^QavN)Q}S=eS@b)%kafB3?-AqL)`I0
z;xwq*sT7HbF*CsPfX#to%F+iW`d)%yYDlA>g9l$9pH3kGaXrbdZ~{5j+uIDZxxtJD
z3INrNcl`Z8-%Z>hkZ=3Jgb!1wOIas136lAjPL$Ynk1iAh1CdD2M{!XVGP^Mwra2~
z*c8(L-QFGYQBsbg+m6A(=KS`T@|(9>mYrXLdApebE{H*K1^fvj8VPwB(#ukb^>B@J
zOy(>F$V-#Ca)FK!YvbcyCaF|#)Km)?Kd$)43#@5%_MR)m!G9T}RnpJ=_C1h_1D|Dn
zCxNlP(y%>=dUHC%6YV8p8o|!%N<{f|4zeer8#(A8-GZ|ie^b|Fq#9<^N!*A{BbEg2
z5~fn}!=Du*pH-F78>GX>`RpvoHT&r`RUuQAl*>9j@ICm01VS|j?prXt!N>&*+%&*MDAV4WMeqx=eJxS87G_cpVh)|7n5LSN46{?k9cFARsEA)T2
zc^dGl0iI^pg4Q){g>H8avgn|RLfVvJv84?a1DzN63{krz_W8E}i-r=@q%upmN4=!0
z#!wJMqnUHsh_>)8y9_WyS=%w<+~f@30cWp2QW<(u37bT$75e85v=gsM=*HZVP40=3
z$IjNx5ucZC>W2npqHRmPyc2l${xYZhk)Hd;=vVw@41
ze~3O|2h-Pis)VpKlhp5U>azZ9JXEuoPKr6$w>s^LC|KgdYGfM`;bbtD%%tO2?$Ua)
z*;pFFWKLqZcPXx>Ycr`-Slc^CayZUU2v58&Q^OEUujd|QIJ$i&0dMHZXU7RcAoo^p
zsPE-CIwnCSw}m!D3saIC5(+hSaZS2K557{xRRY&sbRQ7H$AvD`Jx`sVX1);(3v!=*-vilF|Q-~bfDVOsA0000>pv3=+{Pz|NDd(hk+?hEDn#WJ$sBS_N{*pq7CDPKvlhGMmWElgq!BYL&CDFq
z8fMloyJyxcF>?qZi9%1$^KU%Y=kvX;SHCyE7uV;?_jGqu*rT}z001aBJK1~v$(}!G
z%1Zumqe9RH06-Gp>FNz+^Vwt?xuCKD7!Cx(z%Udn50jT%lw4F*R8&)xhDa-|Eq(m_
zacNB{3Wq{BqN|##vP!dRh&4D04oyH)dMP!enuNjx2arP!GKa>Zarhh-m&Flq=tJ}&
z{!lNwmn-0QF}j9$Lu?+K#bfb=JpKf~i`nHF`wotRdGBx(U5Qz1{uYP2Ei$^o~YKqgR|)
za7HkRO6sC_p&C)Qvu;PjqY*U-axa-eqtJ$Em`03Cq>FE|FO$pUP4GzFB({K^QJOI!
zp6F(DPs~n;W<>U{X9On*S4mq@tvh;uItviNd2Yk(n3*hAaGY$z*UCOg59sq`KdC
zCr}9#I)%_hXzXhAj`#LU_VbAGsHN0miCCdX2!ev3C@35QhoNDWO_hxujd%*am(^R@
zT*(vgI6{tKLeSOM#o#iUyP6TT2o8@!9ikGui6k1SmRuW@7R2JPZYJFm<)K~;eh*ojOf6FLaQx5Odt
zPz*d~c79g8AV$_A@f~<98C%g@k%P*qBvcmH7PI&)*GN}?h`)IL&&wu<1Va;36I?!*
z#-=fb8EH?`z))}oA_LouP5w7o_*od07d1IMS&S`)SHg4AxskBQ0p37dLEN}_98wJ7
zPH^#Ld{}l^c~dzWkM8C4;=Ax{AsbPRfFhx(h}6Q$Lf#|~j)qUpPtsX*P%bDqJs9~4
zc|Y%db7%AC`OjG;S-EAoRfMWnlvgMMirP<|Tbx^1T3B9PUR++BU!MQE_H}t}SvV_P
zTVL~x_JozgAWtBBu*Y5l01|)%FZXM|fBy#j;s349GBz^*)Pr1%lW#l#Ag}VjNU+B<
zwg7-VSZDi7-pS}ipY3RY=+KY;f?fMv20lxst#|TP0x26{n~S?GP#26B8Xx}SA9>#l
zt8HM}XMJIJsbxvrsD6}}rtXU?xMs6EME>i2weX+R9HQzx(p2F(9`D!EP>)l52Rlb{
zcIDq9^mUaP6fC}SzO1^_Gx+0M+Vir(Z|PlUlyY`#(&)b-lD|v7x~Shm|DP#cdZ1go
zUF&&(yAtp5TdP9h1__e*mr?!HU$5aa#?jZ4vPV_}PQIfdf0MoC!lR_0H^#*43b?i#
zufIQg;3MtPB8cs47EU2B$x+kYhMDt4tue_RUOM&d-G>4t%+=(oeFzuQA$J7fC8xlO
zj>C(=yM~UuQ9De2OH4Gh;yjQ6mSy)z?a-dxzL{wigtVFl6n~)CVT#!TndW=%WF3R=
zf#|x}qzJm-?p`B1dIffaqo+Wdc25Wlikw|{vnK*uOW4&Y`Ju}H8gcc7L
zX>-qSpW2;Q_Y#dW;_p#!P4}}wHx!P^H33>*-YaX-d;DU%t*O;}U6fe!>33J0mS5iinB!0PqaD)GRNqFG(nV=5!iQk1R3J<8SZeP%
z7+ld{WnaP%aLZw
zb|?L?HwC9fPAYuVlH8P1?g2mONm8;WR|lQiaFA&TvTTclTOr?_P}{!T^tC~K&D-qR
zAyVgl;jw~&r8rUh+L1OZnP&2mfMArDpD#nu*EY7i4ok*0u+N~8ng
z?|~97Y*_!bdY0Xa?v0$cneHb;II9`MWyj+qH)P>QA$N8<)n^A*&vY6O407uv
z#*Ja2NHDewB|Vs$Y>Xj`=nwY4JTsDYbFIb9J6j(z@z5@`z=_zc6N(v%?LTUeiAs|J
zHlZ9mvojuYB~7V@!xHnO3P6u1#wNPwr_2=$P6F^P79PHy+V3Z%Uw764DXA%!uK~0k
z4WvD71y_^wgZw|<3;P8X21z&x%*g>fq~~bE-K*~*h79VR{XajrYhHaMJLDU2Lh#US
zK-;RV%RY!2ALUQmS{8p1R9v#Lx#G-D7x3;?vb<{A8R>H{O1_vlkf`|!DG1Y^1e
zzXK_of<8=45AvO7{4ET#89!VS8*w(F*9S5U`Dp)udE?~0zjb|Apnpb%)BCWk`PED9
zhVv;EpUxZu$+SeQ0`Kg$({%ZC@5I7jk8F~XH)5|zzF^#5&LZpAhqU7$r-RN=mWHDf
zH-FQ?Pw^Q_(`;yPGcQZcd&lZ|>&iA}{P;<~j})n;T!eXF>-9VQDxO))#m$3y(V1*}
zm(--DGu{>|W5v*EDGeaw(n-h+Sl#(bZ&<(zbl5u5AXiPne)vB4MD2os#=~C&P)E1o
z2^7fG=nX=qkM53=v~r5J9V{|k1uQH-%b+6jqV}fi$QK7}b>_uQZ9?OA!3gKQxOE~T
z(b%kW;efl8jr>z;uy*~*4M$b$^m@;_>u>C;{rqOWgnYG&K4u#Syqj>-U^RMqBWQ5*
zi|5*A0qpRaRD4_F9-sgI@?!=nDf#*jNw6(K*``&7p5bD&OhF$X`RIS~VWYJc#)6ZCyuhp`B7PcD}BUL1~F)Kf=5>d#`q&ZI8
zQ7eCB!~PxN)g}XXNaX|ST7WbIJ{5a&Z&JdwXV)ao4_Fmy1h0X_)A|i>h9e{iLtCnP
z*Zl3VW(s6bNB#FVMuy;;T|}aUYLww@0{XfAE}a{4=W;fKV2U*g1`WGmrD)med8A0X$
z?zxLTY+_mXL}tWw{A4WtOByr6y8Nh|z!orfKU&842OB@4X(Bpa?cQqA{|(IZlo+YQ
zYDZX_1N*6$jJ)z7?-K>p-)K)lSrDcR?#bW!
zsyj%ji??}dnks9yb;c00&b89*x^K2+>~dF~&8J@Fm(0s501hP{2+n!x1F~7iX{AH1
z8{|2nAxZc6M@MJ|$uG?HOp^^yIg6_-wf5;1imiMSTEFZ*X`F(Wy|*=^Z<9*1nqM|o
z!JNINsKvH^tl!rrAI3QKQ1NEkXw0L*nZ&Q&ohI85-`}#Nb63yGK|dF9<4&oUF-pwF
zvVU2dw;s`72lhKT{Oy3YTy8H4d9ceNk*PLhYO{nfr1RP`n=)pN~%R^mjT%VeJycUPZb3A&}Y5S2p
zQO*^6R^0VgMgHp!J2^Jwm?+iwwsv6575mlpin-&VBc`TbUIrTthD?1|Vd_+GQcT!^
z%7*@ACGN`$Z|fIc|Dcqp0*fvgTl_qzers%Nmh|}vc>23$ff`gB6CQlpN&i>nj6;lX
zXl|&^jeos&@K#8K4i<4L#+!xs3-~?nv6t8l9z53;ruFttPIYa%a?J?xplvBq?K78m
zgWwbn|1|bl@bz^Cn3I3lWjRz22RB+)F2)tREbh;e)%R>Yy|;A6XiSv3w-tUG+OB5H^0<_zKaV{(cFlA
z+dthY0go^J_;ayjVCAB5%2`m@YJ=;rUyJrnk2Kt`d(TXYPW&0M0B4}PeWP7)&i?>W
CSy%}G
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/letter-spacer.png b/trunk/apps/showcase/src/main/webapp/hangman/images/letter-spacer.png
new file mode 100644
index 0000000000000000000000000000000000000000..bd6a7b010f4d2e0d3c2e0da342436e90e703fcc0
GIT binary patch
literal 926
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k3?#4J%UA`Z*h@TpUD+=)atT=K#@?&<0t#^!
zctjR6FmQbUVMeDlCNqG7Ea{HEjtmSN`?>!lvNA9*GX(gAxVomh0;NX5Xb6nV5IAiu
zE)VoMV@Z%-FoVOh8)-m}h^LEVNX4z>1PRu~2_ijBfetzh46G&$jMCp5Qb57v>FVdQ
I&MBb@0L~sJYybcN
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/play-again.png b/trunk/apps/showcase/src/main/webapp/hangman/images/play-again.png
new file mode 100644
index 0000000000000000000000000000000000000000..48f2455be98a32f292bcb9e79a90b4f2e5518cc8
GIT binary patch
literal 8607
zcmV;QAzWdKHUX&^B$AWC6wATls8GaxZEIx#ppG&LYCFf}kReylzG00007bV*G`
z2h#xx6B8<~mzbCU000SaNLh0L01FZT01FZU(%pXi00004XF*Lt006O%3;baP0001Q
zP)t-s0000=Yf4gcQd)ajT60=sdt+;aYjccqdz5=)gky}QjJ3wK#@5Ep*3Q=6*1g8P
z#?HpIy|um0y@Z^El%QrI?8NEc@2ZXC4W!X*XBMR>E(M2+@+&`%MI7YG_F*0+AF83aDEwB%
zZ&!NxE@o3KGcMN+F4eYZaiK39mn78L>8MSqbw4eR1o{@zc*FGt_XeL2-~}#Bsj!CIfcK5BdR$b8
z#|woUOQCV0DLlS+#@=ArQ<5FRreeCb=sl&NlIwy76}T4rdFB3q9^K*X;^JgeH6PnT
zx3<+D3@#d+i&zurI*T$sgzKynZdCPqC;T($2
zZ+Fb2Ure#>Mw-`}_gMbObr6bP1gP%)ITrE!9)}aya=IKZqz+RReqBL&y7Boo8eHco
zx`mCp8|nhHKFoK-(zGyRS=Z}L*aqRmrb8jjB;sgmS)#A1L4{aUih5-x&a{G)vADC7
z*I8RvO>6V^`nGP1r!i5f(u#NI>-9=ibzZo*aL0_{Ot!K76~mvh97b0tGD|jd8*`em
z7u{qaey#40;H=Fe3}y3A^XZhJILopQnBlgH(tOb>hmZXYxUe~gi*Lf)i%s1)%VMwkn-Za_90YYV+i5lt}s2Dg?Pip7LfHhZ`5SArPNK2EBrW|A~k7L
zWeIsUFp6nev8yR1(XIV{v~`6T<~rg!sM5o9EhNo|fSL7{FyD27S*Dz
zcT^=*zPePWqJ+eNj|*lr;Kuy1pVoF4D>JlpfW0rCWdoA9g=*m`O#W>}YHxyqM>yJo(@
zT4@s4S=-<}e|D9MkWN|}tP}imiR;%!=u1`%BpjS=xB1BWPxFCAdgcx$&~>GahNW3a
zB`kd<$`hpjeyv1{u{)7
zOF&p(l-bTKv}g(ha=C3w8yq9%E2)KK(}ca&cagJirJfr2Ze3FyblnJK=%GmUhi1aZ
zTMIu9B9~jy!Dz3vGT7baHp3iJudr*hQy?k?2h$l(#3Z;eV9K=JMZFo}V62k8x8|0Y7uMp4Y;`M;cm{;$|C~mh@Up~Py?9&@vkJ$p8
zEWB)Sj%9RC4dvyJ5Cv%|kFeCxiCQNOZ$_p6xlF5pGrZAbK=ok>(k9uTMhnHPe--5p
z2Mh1&04vmnwu5gidpEX46dxNhb4QGE_j{1T
z;p_od@XD2!v8+_3!k@8{9l9LK>R37|0m+zWdZiO|7k~uVEEY{l(=w&xzpl^2v|0i)
z*n>@oKv+d9>jdVhn*8&{>!G16uq*F$6}voOQV7~D8%A1?dD+aPype#f6wux#pBw<9
zwgz?CEI4?fp^EtD6!*ZX;|QZB!i>$C)>%+5Jp}GP&n@W2DzIzEFYEgWXW!JsHM+5P
zt3#3P;JD5abd`1Z@eOsbf;P4lEti^iWI94xI=G#smXos$dSSPdZT3y39
z)P8eXaR|=EScXy^hv7GIM5&bc=ZPRqoZt~MnHp-~!khU8>NkC*ukU+U;zHTFulw#p
zEvgz02o|%e%i{atm!!$2L)CiXYjBUkvEW$JAFsDi#|LPj9ptq9cWS72V(#Z
z*4EW+SA0J(*)mOBE%iV`pCedBra!RnJsU`p#078ohR(8ILkA|?N|@SU6K(%+Q478F+S}sW
z0rI$98X4#UFe|^i81U|z)|>3%wBD{XHJbv0vy@NaI7ytcOnYDtz}rpBqaVk!Lnv0A
zFQ5*5gop}#2eMT@+jpJ!-;xLH
zZgN1!UkrQ#L*KzidwY0E-C!*F
zCnA=}M_90#TsqQQLnuWbXA#cZbtQHcH;y=^5M-AcgIfsTvQUn?gHI9yLwh`r7xC*s
zpo<$afv|zlK14Fj+&?agV9c38`VoA(LKMg1owk%jE%X#{8=z~NP0?|kScewzL4?>_fJQ_%
zL4d&+@bjJ(*bVCF_8iZTpLx9f{IndrvxRCufByRQOP;?S4u`k5x8j@ecHkGj*S=pr
z-`;-xD*ir>Wr;{?w`&-u`8DI
zYHV~B2USLdeC3e0-6@E`fl)l9dzvRfnLRykqFt#GAOKv<@}d5^5V)QeZ@b-aUNDub
z!aG4W-c!)RIKue6<}s6bX4vw3_t6T3p&jAOi9Y?|3Ixq?U>{3?2}3LtYJZN{4Ts5x
z=-~XSoP<<^Isjl_D#9?(Am~*r+I5A0Uw-_c@0}4unEAybCj;?Sw{=a(
zJphR^C-n`yt}%o8S)87B4kmJ5ZUm&-NbU$P@A7RCqnaPZskvYAX4|fBdjL)`nQ<5+
zV%lLCoTK_9ei+^cCSzcsVL%tT65z#xIC2fn6u)8P(u?Q_xX;q>)Vq*+rmmvzxT7MU
z*j;!D^^!dJn8XOMndiI6{UTJNOP3sA67tsNjvSa!G~zt(t7%)fS?EK?FI9}nxe<2r
zQqls1(ha9yf54hUqKy{BNqD_Xgr9hIUIc3|^NR%nv)K9qs_L*27`oPLxCMv{Jp*Fl
z80v5Ar~?3^Pk?)0cXI%MMm)BzL{Zgxoo^&|=T?^}W!xBJ_Mq1r2ut0EOz?YkhHt^02-wTuhDo*-3hNHmi5x#|D
zQx1nHPl`SXdXbqF1Bi8koKi|~JA{B=7l<2cmM{>(HuW8fF&71+*2s?5?Y9u^$7Cb}
zV<jn$JJA_B;28ja11ap#{qJB0nL!qVGyqe
zoQwU;IbP^A5Ft$qpF{hWSJ69QgR!dUI@?D3VYNHkdBB@){FZYvS~w(f0X#wUEGERQ
z0;hpmHb-7AAI#)VWH1AMw<+zeT3Zbz-)kS?9K0GLXi}A<uZhCpTvtq_Z&=^;^KW
z#Y^^_iuqOlYG!#D-nK9%{=rw#goZA7`&R;IP?dC1Lj7pUWT`82nz!ZlAuIvgdsj}H
z9$lz~`NU;cO6;-4RLz~fvkEGf=fRasm!F5zkP~)>VKM3WMUrN-W<;38>U;?+D2TQv
zqINAXVDqSFwGS-cSo@9PmV9{|10Axc^9ZuO5YJm6#GFs$}0SOeE;QLap9OfHTyE(KT&ebxEw{`8>
zkD^oY#<~dn#NQYwAQ?`lLhuE4tdvMPbaHPq))UAj!oFqMhioR=(lg|l24FGV2Wr$ywuf)FG6_
zX6mWU6%V>VyxB^2;&$8g?@C)k2Y4&D^}*ov)EGV6J03>p4hOMsWgKJYt0VI;m8vQh
zIzoBK@|lFdFZ3B!leVbW+9?|qaLqQomSjDNLkQSDWHxLa`*YiWgR2XH^UQl3BwD4W
zOHD@dfnZvmY!Uyy-f}iA2fIv@Owb~|>?uOuND*)2UyQ-I?pXYA12AYfs<79=`^ir5
z@#*uP(=ARZ`-ci11Tir8iX8%5EfC(X?fb5M0H|>5fTH!c@)@-j>&d6{Haz{`a-})V
z{vH+%!a2`3-lk(hHd}Gecpt_o%Vb?cbh>(5b_`V<2PiX~AfornaNl(16aiCo^Slzv
zq@mVU?%V^AAyn^(SrEKy$$BaPKt$xB?d}qK0aWB86fL+>!}=@+x=d7dysWIA_(
zl*(+0(g|al**DM2mdO_DPADV0&^K6A=&dN(Db_A#X9Wg2giGVL>$T2Sx0yfHqn2zw
zxt4~>3jFg$G;QB7F-HY}r;Y^H%?If9JyZALJM?0qK471L`W-+R4tfg7NX>GoiNnzh>)BFm9U`$9O34pD0rG2e9lx?P|119
z)dy{xMiL)hfr~&5J?vyr_C#cii0=89!S~*J{%>DmYt7O(lXZk=%>9!($uAXzV<7P+
zv@XIxGHqtPn?Nc_bTdJqjFtLbYc#8U?^Y~K?YgrMl?0?m1i7QTobsaJQ=ss$+WN_r
z_rz>utfNinbz@rXtG2@ueGQg*7B4kqr1jzM4m?a}%^FMHz07KGk7y1j^NZa)Adu0@
zEIZv~HLWp4){Y4Z5%qzpLfw9p{
z{c-B2i~}ReCK+nw4}7fKskVSD7Q)ql#DRXk_Xsi{64)K!OAq%y_}8rfeQJp28#>#d
zO(XTZyZ_VxhI6$k<_sI!i>NNlp$VLC;2TWeitxX6`n^Q}1FnIl3nIS|#`A9J1{KPC
zZH}ok=C!^g#eU)K{Tsi29pv)^Gi2YU&vJV0+sX>lXTR=Axo<~VmdEm#vuu2Z@#y#EYJ2}GS@dcQ9W&1M
zdw8QMn#(ZJEqN>;}H1LLk;W$A6r3AAf3SZkqjnyzD;>#SHJ}0KXZa
zin%u!`#!QGCB(S-8&{1^ITzJx4K^3q7aIe5r8Jw}?4xUMMH%UDXpklH=ivK+ZI1?Iz%^ZEbr0qOHuG)dNu3?4|
z6q3HZLIl25Ok}zC-N$?6@NeVPngxz~PT`x$pSD;NI5K=&vgrKQFnURcKg!9DzfSCy
zPy<%pw-V*=7hmx$?Gq#zjx=~Dd<>a=;NvBpBci)e3Pj_mhU$+}Zr8e>>Qbumk2;>p
zu{;gKs7fYZSXoKzCV-om1R1g#Mqf&UEjdG$r&a>ExG?(7A4y_yA@uo6HSA*q`bJ=H
z?S=Txe(G;2q&cB&Kv2&_725}*Wi%qxRbZP0)aMWY0^#`%|1#?~l%C-x*kmDB^)IXL
zG8`EPVsANRBA~8<5r;#TYMSH~mh}b60b;JPUyIo~4b4{p3q7Oq(ATYpuX*pfu8ma=
zbX67Oa8V-ybma%|4J;f~>B`GqM~P)M9EZyh-x-d_!%3Zrfw>T%q)Bp0@VL1OubPDp
zc9}HYEEY`EH+i}!e1B#-81E5(q?h^8uOs%X)CCBh=r{NS9Pnfr5c{(!f%$g!4R|1D
zBBKmXibIF!2j+&6XXl}W|I5cbjseC+6RzYSH>4Hv`69(|Va}I<=PYg)fGT8`=3?tA
zTai=GUsw}a4O>{}+UB5l`J$%aS8d5XNUyGGPNLfu0(OO=yaeUlSPi3thMiP-D9d}1
zKn;gW^@i{WO#M;*;mwD{lnsq1_|iarHlZ$|bGJ0vdCuHIAh9gW|6A#)ATXY2KaKvU
zeSE7iJeenvQwiop-`l4sQHlw5*RV^dj(FBOGII;HyzB68--EH?sp9{?$4>&ZN$@ir
z#+zZ+%VLJl-_uMR666by)^uIAkoY3my;&6U#LmRk)gA+)M#`twgasDbr+V29d@IqEF)+*toJ0Et2mOk;fp
z#srbJ@9sTsY^{Os==}LVXTP0D+mdKC9Xt}28
zdc88#Auhgtv7Qs60B++Jnd(_$h-5#vY^Vm|af|Q^q}28MQ=aN~bi=udL+6}3RBnuw
zDuXJ|_@5zYJdWe=XHdscjk{pfqJNE%T(vPDF2$x*s1S?K+KxCmSO|ur6tjlaiI-*L
z&%@SDUn6L1TSH-EQwN(9ZQXwsPl-nWVhCdxMABt$(S>*Q5W`>lhF*?VGX`RIh5bG3
zElNhZYs{k#pMX@Zw<}amIEZJrr?jv1K4e!yCH!POwWdTY8s>@{(h4~DQ)9m9A1q7T
zw-ixYneP4ZMn1YOM5Uqw9xaDU9GtqG2XHc{sS&mx%L>fD?ZX;fe!!MCSqHkkFn0{#J5x#s)`yNu@bc3Yk&V`t+k
z<>l+1=A_S26siw6rT4Y?0SV;Fw@p#ry1K{X?a(0j7jZS^Gbnf{)k`d56P4H98
z2kNqk34-;S-5w0g_4>J{bZq$fjd9fc9C?&vJ-Y+9JrYER-GkK5<`c&4>^sj}7&gHJ
zf<7hrgC8Q#QN(e8>K)5-s48gNz*u+-FH}V=>Q2?pJ_~C>Q!U78F*zTgw{U@uPOPPd
zZU4P}qUAsbe)EIZeKAj?hufpyqYjcg;0$yWLlGO6?;e#iL;h;&JO8Ryq62OAV@Kgi411JmZPsbs%BmO#26I;`-|co|&hBQO3i6|!$=^An
zQuDkPlK~!cv{HtOlBi{pPxk0J2?Lu62(BTLXCUo5Jdz*dxq{nc%EFyhRL);w#c*#>
zz${Y6{1H`E;{QkgIe6Dl+qE>xZ(KdkQjU@uD}m=-6d3_>c|@IH`|_xLrOgSo{?Q+w
zt!<2LdUi94_Ejv~vw_({0wIg9(`9mu<%`2x=5s-GW*OVjxe#9I6sH)><$oDN02X#u
zFcySVr|I;(GWLez=fh!_JZK5VHTY-S9Q3uOl|Tag^S)_^mlLVLEK652cF+Jj{~zmF
zvSUzmkG7JmdYf46r}MK~v~VxJ0GYs~7#0|Xi+jTg2h~n0V!4tBtO((rd|!0FDnr#d#PFx$#Fyvjz`zKoIaEsc2Qzw9
z_ib-kFp{>Oh7Rz5159=
z`sj!&yg-@-_+;78=RKkak`>M}uDZ#|NfOA4k?g9KT+gHBV3RaJHv)$UHS|xuBb=)M
zj=3?ML!=q(27s2aWLK_>%ws!Y8-UFHnp!+NTdLVvAcx}q%0A6H9Tqp!xTo|HCz?iE
z?h`Drz1N>~1JJ^AaJ~Ts*}9Qq->|u!{n|ldyO&v0DrO7+&f`mLN&N5ZgCUruifSpI
z+vJtF1Jj6uVjOM+Mry$_Njf*AjJiC8^=#tLn3R}?{VO~7en=xH^V@9fXtv!5Gi(%g
z$}lp9@b>jRfepCEx;G<-4zTR0`s-a7&fbA{aSXx-o+}y#aPBfxWh`MqKVgkP@+d8|
zGY=gl-;63r$(2W(CRRP~Vg7H;^mpzq(O^t|*Ea0zqo>Pf)$?enR!~5I=f-pl0R4;b
zv1L86W?7%9P}~15{@eIXzo!}haAhC9o&}Senb>*OFf%sg)9iXd%+9tq@p8hg4_r#S
zNy~ZNxVQ%uzeQEqj>MB__nIk#D%LhxexG2bv5tM)d5VZXn`#Qw!18YcZ
zO4=^K3ua=fz_Vfq_byNBrDVIMPAr{0EdTr^mw%b^F+d(of>I^DD{GJ#RkO;=Xgsse
z5pQC^+)IDvwjEvvP=KHZ(JKIE&;ITDOVKc#4RjQ^1%U%1q~PEGDZ%qWSx-LE92m*!
zZUW*VdOVE71Pbs4AC@H_6^2Xa$u5RN&rGtn+jY(zsoUcw;{i9gA#7%@4UfAcwJX_X
zM8D~k%z)qcoP%a>6Hy4(7C3eY>)Iif|N)Mr1Q>m55amX$yPHq%$B1fyD9*#l&vH#Zahi
zk`bTi`IjXzYrF4Q=h;_mV?Z`>I34r`%Y=3x+MBe?mBMLF9f?L-_|k5B*b~e^>!7
zlC<5&S`_K9pEbWPOf)H1OxPI0@@%|(l
z$4ry7&C6KtJ+h9e&`C-QY`R$&+Js7a;TCB*l8VuGQo(GkR6w!Pz_L&nPHd%-0zeLn
zHQ@`)sFv)DYkHO{H4hUsEdzM6FsGD8V3rzjpLcN>T?Kx{-3%TB13wopPN~Cr_&@Izl2}H;rL#tfRU2Thy-D
z($w1^N2+=3rEi=1bMOG`8Wn7;h-dT-Q%rUE_t*h=4C|SBw6-xhgl4^@IMR+%0Oiar
z~|%%j4wEkXK~Xevr*kvu;~9Eg`U2a=%<+te8aoBu6EP2=8A+6Q*A358Nzkf#pPJ
zx{0}ZSk9WKy<@;bH^%(OlG+dyPtp6TI;->OhU&qeC|Fc=sm@GTSC4k8f>+Ym^p?Lh
z6ajkmm&~xLZ9Z{FOWEGFVW9tH7q;a|kK8cq7#~<3Y+>JW-`Bf+{PBzD*xn9@Ux&AE
z@d#~;p_9HAwDzrTEBJgk08-Z`fV^@b=c#iCx@JyUJ
lSWx#FX{+cQ82HG${{zXYbs$JlT_XSh002ovPDHLkV1jxPm5KlW
literal 0
HcmV?d00001
diff --git a/trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_-1.png b/trunk/apps/showcase/src/main/webapp/hangman/images/scaffold_-1.png
new file mode 100644
index 0000000000000000000000000000000000000000..f0d65f8cd0906e4a5f798702d67fb659a4370fee
GIT binary patch
literal 9806
zcmYLvRa9I}6Yby@oCF9KG!Qhn2ZFmpg1f`uE`z&6a2PBEw}BzJ4({&m5ZvwZ{r9eQ
zAG&*0?W*dk-F@nuhZCW!D20js5gh;kV9H2~s{#OU)Ng|d72!=2k}ux$wlKL!{BRL-
zGBa|q0@{C4x3V(>s2RC@`pWZ3)Yak>I~yDOCw2~gP7Z!{zE8|-Tx@KV0Y~6BKNJ@k
z1qqZXI7}>lqB2%}t2Y&zgY-{l000B;zX3P7;`j8XM6?i95Cs5g;xL|!kN^Pq5@mUH
z2?+}cNlQs-D`|N<`JWy?4SfwAqa1C+Y)$-4v^})#!|kDl`B^hfO10MsMP#bw$d9Ng|yxP3s
zncGOOnyw_@5HjE
zveLh${;B?f>4CrqpmU6KL{3C)NA2&1-=lM*E88pUyX*VM`%4>3$;HVt%QJgNdyTz~
z9m5?Xvm?FZz0=Fng^7rn=6$&f!iiH?7>7TwO2SA8tSNy!FNx#<%vjdd7MN
zrw7k2&*shB})2o5$wI4*wlC!J3vgmv;_#CKe{vch>8>
z>+|dKTL)Ux%F@!y(_;%_>$~dzH2w)l3phGG+CSNc_CRM=W{&*n+@D^Yo?V>z|MCyY2-?`&0HuPiZ?Es}?=G$`F0U`IZm!1X
z$E|{`fRRA60JGqX;E>D^brbI!Dz>)g{(N!$l*b
zBBOn%T@k2Q^0y?nI@dSFx4gN0c6GLEv@5SJZ+dB3)lpU7N58VAQqxs)ZFjApu3&C$
zF1;*$bau3Dpv^YaHm)#E%}Gt&S=}PY!X?J#_U_g^&|KeJ-#f`$*HicI;V!NqPS!^D
z@$vED@!^k*&e_`~hI3I>R0D|Y&YJ@OR9iCQqUs)t$GVR?+H)DJw$L<(uR3)?8@wwE
zlFKl%EzB5X9A$Bw@g8*4aCKbTFI<=^>Vcb>WoVQIR?;T4^>!JDL|Hj7x^#RyW0qZ3
z-t2?nEDmV9sl!7Sab{4{SAw(j%a=xS!wUDBS$EG{=r_O}<4fc#As9eJR-qL9Cn9X<
zaH`~XXjM+?G*xBD@*oV0kS^cMuQV54)wp#K6;2+2m*?!?$w6>?V$#>ns*vZK*qreT
z9e=H8m5Hfolrr`gLGf<~9L2>FB%~uR_Byy|F1}hY=-YSo{TC$xhj03?_s~6z*F+2Y
ze@igIi_5WMR#`4`w=c6@!U;iJd|bq7$EG6#8ClbnhhA1;Tqa~uT<*01V)?uIknBc6
z9|=JVE7bs~XXs{|?>kX=&6d{E6s+*YP;Ev;$>m^1q=IA-wgE==*?~ccofN03V=~t@f8sS#hW`rx)80|B-|W1!n~u@DQb~HN*F;&@KJq{E
z&3omJLbBdvjaVh@n7yw-gCGNq%q(z^-#y)@@VFzI|Ge2h|Ka=@<2B8Ad+K#MB8w}p
zafy_erG@$Po?T8}BalK3@2Iv?$!RA#v%nLvn5KR`>NJO(F_Cbf{fYjR$>J*3Z1$(h
zm0J1Vq}~PUnG8Oz2br|bkMNOP?voC4mAaFh
zo8>i@A&m2Xo?otz_Pg?js2k?OgdOBcD6B
ztQVGc;Fx=f%M8*2iloSQq2e={Zgt0h8}tW!?o*Ww+_)or!(-UdpzY6`Coc69leOeU
z?OX>}Q0EUb)+1Ll-z2QQAM%BqCZaUwI2ppzc-0c-a{T#XYT!#=
zMEtj&@q<`FSB4w!+vSB9h=tV0q0oHlqbNcfd-65ZC1Kk$7q{wiM+xtbVg}{$0K|s~
zU)7AXa?EOVU6Vh&@hoceTelkHk+gJ8d_Yh+jWz`)d5Iu!-4SjJn72Er5BL5%FyYi2
zwryMKh77#F=s;cUh#P+Q&zV(-nuk&r|JP3K%(Hd^*Y!H$BEZD=z395@x_0ueKwrY<
z2fOU@^$r?a08-Ds%(&RGHspI#`@ql#OP0L?36y^kPm43eaSZ@@tIE=kNN@{
zs~wn$gBDxdQ;a18=Wj^h$Evh5U8{*c85tD`#Oki{&s=L3v``_j;0(H1^Df?2Ulf|zkwP=tMFQVfpzhmB_-(yl9l2X?J?vtJXf
zoObIK8BtDgc4<@gL-%Lp6!lo_m?tw`JRqS!wslfP-9_8MMX%y_PNmMj7n%9<>J;Xz
zRWS~Q$@f*)NSxI5`04{Ivq~{+f1%J7yZpK-EfGDXLy2v~(}b1aUK==>6RyNv`vt>G
zhwKO;BO2hX=%|heLFc`YK5UR(Pj2qcIm4KK;ts8(=)x@PEf98K
zlaQit7^b%5WpS2~=+R*n;}wUepr
z)x>I0>=7qhEg*I5LsX$LRqh>vQ2sB0)?h~EgA0O?iPA1q40#G2o~c)0rl4=EBy(3t
zexxjE?mPMVBTr9!Y`;~>=${_Jum@DW-c?eooJtm8m1{p?Eio>q?0LCGkj+(~hGVXD
zRAyby9>l!n%=VauMQ)}(TUn5mKk((r9v-O>6oGT?eK=2&0t;==v2B}VcxCgZb~*|-
z5h5`Kh_`i5HvUQAW>A&&EMkyKD1>kp)+Vi-P^H~YoJfT@*h-qiQeAY6bOlY`i}^r|90DuHh6g_6Xs$J5L=Flc3mNN1
zMP>K_!!K4}*=H~j#TAg=+ZOv?0ghZD1H$2X**57G@^EuZRF?yuj}tm)mjXui%7&$X
zV#~Urv&@X>^M=Bf$VG#Hn_VkQC*6QIv18)}A4u0{U
zz!LhdHx^b6HbN5L0-e4LwSURTy5Sl-?Y`O|v9e1+Zk2g4>mhoJg&DKkm@&+~NwI7s
z%po^6mNAKrbkU#E)l&hE(cj_9++|8+-j7bTowbk0a>ew%G817-28V}A~Ut@Z0eTDZT?U&tns{$dkTCd2;U~<<+{$-fs#VCkHsNgCPISj
zbqB*HcR6oGJT6XX0usO$yRpgCDn__dnkF_@o9E$70cFc@ZFlq&TgBbmVoJxP#|;()
z@cmeHOtMIeL?S4tJ~?qv#$tV{9!5F__tAcR2k#bm&G*oH-3Iojvu8a|l(+;EE7BBs
ztB<(<;Iqpa5s4Q#%TV-p;py=n0@NVrkRTUI!Z0nC8Fv@l;4Fj*o*NobG(UKK<_>f&
zF0CF}8^1&R-TG|k2VE07-!m9EC&S`V2x)<2J62_Ua0;EpB7-a$g_T!&Um;vIfEx*s
zSjjMAJDSLQ*C`LN*@ZHb3BiEYZ|LDTR8`w0S?5ORNA6i_9=&uPN7yUYf#+4Dx#^-U
zScG@^t|a718Vkbv;Vl9h48
zxsV@4Kg+eW;+DnNPq1kjMBw{Pb7Uy3X^kZcZiIFphxU>zX%HSN45V~<6|xWdzEraa?*Mvr
zG{5gu0VrrzMls;Nt