You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by hu...@apache.org on 2007/11/20 08:38:01 UTC
svn commit: r596559 [1/2] - in /struts/sandbox/trunk/jpa-mailreader: ./ src/
src/main/ src/main/java/ src/main/java/META-INF/ src/main/java/action/
src/main/java/action/user/ src/main/java/action/user/subscription/
src/main/java/entity/ src/main/java/e...
Author: husted
Date: Mon Nov 19 23:37:56 2007
New Revision: 596559
URL: http://svn.apache.org/viewvc?rev=596559&view=rev
Log:
WW-1399 Initial check-in of a JPA MailReader implementation (with CodeBehind).
Added:
struts/sandbox/trunk/jpa-mailreader/
struts/sandbox/trunk/jpa-mailreader/LICENSE.txt
struts/sandbox/trunk/jpa-mailreader/NOTICE.txt
struts/sandbox/trunk/jpa-mailreader/STATUS.txt
struts/sandbox/trunk/jpa-mailreader/src/
struts/sandbox/trunk/jpa-mailreader/src/main/
struts/sandbox/trunk/jpa-mailreader/src/main/java/
struts/sandbox/trunk/jpa-mailreader/src/main/java/META-INF/
struts/sandbox/trunk/jpa-mailreader/src/main/java/META-INF/persistence.xml
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/Index.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package.properties
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ja.properties
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ru.properties
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Create.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Index.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Login.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Logout.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Update.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Create.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Delete.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Index.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Update.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntityManagerHelper.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntityManagerSuperclass.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntitySuperclass.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/ExpiredPasswordException.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/protocol/
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/protocol/Protocol.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/protocol/ProtocolManager.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/protocol/ProtocolManagerInterface.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/protocol/ProtocolTypeConverter.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/subscription/
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/subscription/Subscription.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/subscription/SubscriptionManager.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/subscription/SubscriptionManagerInterface.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/subscription/SubscriptionTypeConverter.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/user/
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/user/User.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/user/UserManager.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/user/UserManagerInterface.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/user/UserTypeConverter.java
struts/sandbox/trunk/jpa-mailreader/src/main/java/struts.xml
struts/sandbox/trunk/jpa-mailreader/src/main/java/xwork-conversion.properties
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/META-INF/
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/META-INF/MANIFEST.MF
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/WEB-INF/
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/WEB-INF/web.xml
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/assets/
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/assets/focus-first-input.js
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/index.html
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/index.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/@form.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/create-input.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/index.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/login-input.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/subscription/
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/subscription/@form.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/subscription/create-input.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/subscription/delete-input.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/subscription/update-input.jsp
struts/sandbox/trunk/jpa-mailreader/src/main/webapp/user/update-input.jsp
struts/sandbox/trunk/jpa-mailreader/src/test/
struts/sandbox/trunk/jpa-mailreader/src/test/java/
struts/sandbox/trunk/jpa-mailreader/src/test/java/action/
struts/sandbox/trunk/jpa-mailreader/src/test/java/action/HelloTest.java
struts/sandbox/trunk/jpa-mailreader/src/test/java/action/RetainTest.java
struts/sandbox/trunk/jpa-mailreader/src/test/java/entity/
Added: struts/sandbox/trunk/jpa-mailreader/LICENSE.txt
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/LICENSE.txt?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/LICENSE.txt (added)
+++ struts/sandbox/trunk/jpa-mailreader/LICENSE.txt Mon Nov 19 23:37:56 2007
@@ -0,0 +1,174 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
Added: struts/sandbox/trunk/jpa-mailreader/NOTICE.txt
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/NOTICE.txt?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/NOTICE.txt (added)
+++ struts/sandbox/trunk/jpa-mailreader/NOTICE.txt Mon Nov 19 23:37:56 2007
@@ -0,0 +1,6 @@
+Apache Struts
+
+Copyright 2006 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/
Added: struts/sandbox/trunk/jpa-mailreader/STATUS.txt
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/STATUS.txt?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/STATUS.txt (added)
+++ struts/sandbox/trunk/jpa-mailreader/STATUS.txt Mon Nov 19 23:37:56 2007
@@ -0,0 +1,123 @@
+JPA MailReader
+------------------------------------------------------------------------
+
+Quality Grade: test-build only.
+
+----
+
+The JPA MailReader is a best-practices example of using Struts 2 with
+the Java Persistence API with a standard SQL database.
+
+The example is based on the original MailReader Demonstration
+Application and uses a modified version of the MailReader JPA package
+developed for the Apache Shale Example.
+
+The application uses the Struts 2 CodeBehind plugin that eliminates
+documenting Actions in XML. The Action classes and pages are linked
+together using convention over configuration. In some cases,
+Result annotations are used to move between workflows.
+
+This implementaion expresses the business classes in an "entity"
+package. The business classes are designed from the ground-up to be
+used with the JPA. Sufficient annotation is provided so that a SQL
+database schema can be generated from the entity classes. (See
+RetainTest to bootstrap a database.)
+
+The persistence logic is contained in a "Manager" class that is
+associated with each entity class. Essentially, the manager classes
+are data access objects. The Managers extend a superclass which
+provides data access code that can be shared within the persistence
+unit. Most manager methods are type-safe wrappers around shared
+methods.
+
+Each business class also has an XWork type converter. Most often,
+the converters use a substitute key for the conversion ID, rather than
+the primary key. (Exposing the primary key to the user interface layer
+is considered a bad practice in DBA circles.)
+
+To provide maximum portability, the internal primary keys are UUIDs.
+The entities are based on a mapper superclass which provides shared
+code for creating and managing the primary keys.
+
+The business class, manager, and type converter are all stored in
+a sub-package named for each business class. Essentially, the
+sub-package is a resource container that encapsulates all of the
+entity's data and behavior.
+
+The Action packaging follows a similar strategy, but also creates
+a resource heirarchy from the entites. The "root" action package
+contains the "welcome" resources. The "action.user" package encapsulates
+the "user" resources, and the "action.user.subscription" package
+encapsulates the "subscription" resources. The nesting of subscription
+within user reflects the one-to-many relationship between a user
+resource and and its subscriptions.
+
+Since the CodeBehind package is being utilized, the folder structure
+for the JSP templates follows the package structure.
+
+Each package/namespace has an Index Action, which is usually the
+superclass for other Actions in the same package. The Actions
+utilize the Managers to access the persistent data. The default
+constructor for an Action instantiates the default Manager, but
+an alternate constructor is provided that could be used to pass
+in a mock Manager. (Accordingly, the Managers all implement a
+specific interface.)
+
+The Actions provide request-scope User and Subscription objects
+that represent the resources being edited in the current request.
+The pages record the User and/or Subscrition resource as a hidden
+field. The type converters fetch the appropriate entity from the
+persistence unit, so that it can be set as the current User or
+Subscription object.
+
+Of course, the hidden field can also be expressed as a GET
+attribute, and this technique is used to restore the current User
+after a redirect. Overall, the design can be considered "RESTful".
+
+The logged-in user is maintained in a session-scope "Profile".
+
+
+KNOWN ISSUES
+
+ * No POM is provided. Dependencies include
+ ** commons-logging-1.0.4
+ ** derbyclient
+ ** freemarker-2.3.8
+ ** ognl-2.6.11
+ ** struts-codebehind-plugin-2.0.10
+ ** struts-core-2.0.10
+ ** toplink-essentials
+ ** toplink-agent-essentials
+ ** xwork-2.0.4
+
+ * Toplink could be replaced with OpenJPA.
+
+ * Need a routine to autocreate the Derby database at installation.
+
+ * The index.html is not redirecting to the index action.
+
+ * Not all of the persistence actions operate correctly.
+
+ ** Delete complains that the entity is detached.
+ ** After creating a Subscription, it does not appear on the list
+ until the container is restarted.
+
+ * There is no global error handling and logging.
+
+ * There is no access security. Anyone can access any user resource.
+
+ * Despite the scope of the application, the example could include
+ a demonstration of handling optimistic locking
+
+CURRENT FOCUS
+
+ * With the application structure in place, work is now focussed on
+ creating a unit test suit against the data access logic.
+
+ * With a unit test suite in place, we may consider using the
+ "one transaction per request" strategy, if it can be reconciled
+ with unit testing.
+
+
+========================================================================
+
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/META-INF/persistence.xml?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/META-INF/persistence.xml (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/META-INF/persistence.xml Mon Nov 19 23:37:56 2007
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+ http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
+
+ <persistence-unit name="entity"
+ transaction-type="RESOURCE_LOCAL">
+ <provider>
+ oracle.toplink.essentials.PersistenceProvider
+ </provider>
+ <class>entity.protocol.Protocol</class>
+ <class>entity.subscription.Subscription</class>
+ <class>entity.user.User</class>
+ <properties>
+ <property name="toplink.jdbc.driver"
+ value="org.apache.derby.jdbc.ClientDriver" />
+ <property name="toplink.jdbc.url"
+ value="jdbc:derby://localhost:1527/mailreader" />
+ <property name="toplink.jdbc.user" value="app" />
+ <property name="toplink.jdbc.password" value="app" />
+ <property name="toplink.ddl-generation"
+ value="create-tables" />
+ </properties>
+ </persistence-unit>
+
+</persistence>
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/Index.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/Index.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/Index.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/Index.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.struts2.interceptor.SessionAware;
+import com.opensymphony.xwork2.ActionSupport;
+
+/**
+ * <p>
+ * Provides the Struts-specific Business and Persistance Logic API for the
+ * MailReader application.
+ * </p>
+ * <p>
+ * Generic logic should be pushed down to the Entity managers or another facade.
+ * </p>
+ */
+public class Index extends ActionSupport implements SessionAware {
+
+ // ---- STATICS ----
+
+ // General Struts statics
+ public static final String CANCEL = "cancel";
+ public static final String INDEX = "index";
+ public static final String NAMESPACE = "namespace";
+ public static final String NONE = "";
+ public static final String PROFILE_KEY = "ACTION_PROFILE";
+ public static final String REDIRECT_ACTION = "redirect-action";
+ public static final String UPDATE_INPUT = "update!input";
+
+ // MailReader-specific statics
+ public static final String NS_USER = "/user";
+ public static final String NS_SUBSCRIPTION = "/user/subscription";
+ public static final String SUBSCRIPTION_USER_USERNAME = "${subscription.user.username}";
+ public static final String USER = "user";
+ public static final String USER_USERNAME = "${user.username}";
+
+ /**
+ * <p>
+ * Indicate pending "create" operation in a CRUD workflow.
+ * </p>
+ */
+ protected static final String CREATE = "create";
+
+ /**
+ * <p>
+ * Indicate pending "delete" operation in a CRUD workflow.
+ * </p>
+ */
+ protected static final String DELETE = "delete";
+
+ /**
+ * <p>
+ * Indicate pending "update" operation in a CRUD workflow.
+ * </p>
+ */
+ protected static final String UPDATE = "update";
+
+ // ---- PROPERTIES ----
+
+ public String getLocation() {
+ return "/WEB-INF/results/";
+ }
+
+ /**
+ * <p>
+ * Provide a local cache of client properties.
+ * </p>
+ */
+ public Map getProfile() {
+ return (Map) getSession().get(PROFILE_KEY);
+ }
+
+ public void setProfile(Map value) {
+ getSession().put(PROFILE_KEY, value);
+ }
+
+ /**
+ * <p>
+ * Record the CRUD operation in progress.
+ * </p>
+ */
+ private String input = CREATE;
+
+ public String getInput() {
+ return input;
+ }
+
+ public void setInput(String value) {
+ input = value;
+ }
+
+ /**
+ * <p>
+ * Provide the session context, or its proxy.
+ * </p>
+ */
+ private Map session;
+
+ public void setSession(Map value) {
+ session = value;
+ Object profile = getProfile();
+ if (profile == null) {
+ setProfile(new HashMap());
+ }
+ }
+
+ protected Map getSession() {
+ return session;
+ }
+
+ // ---- METHODS ----
+
+ /**
+ * <p>
+ * Signal an early exit from the pending workflow.
+ * </p>
+ */
+ public String cancel() {
+ return CANCEL;
+ }
+
+ /**
+ * <p>
+ * Indicate whether there are no errors.
+ * </p>
+ */
+ public boolean NotErrors() {
+ return !hasErrors();
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package.properties
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package.properties?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package.properties (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package.properties Mon Nov 19 23:37:56 2007
@@ -0,0 +1,106 @@
+hello.message = Congratulations! Struts is up and running ...
+# fields
+user.fullName=Full Name
+user.fromAddress=From Address
+user.password=Password
+user.password1=Password
+user.password2=(Repeat) Password
+user.replyToAddress=Reply To Address
+user.username=Username
+# buttons
+button.cancel=Cancel
+button.confirm=Confirm
+button.reset=Reset
+button.update=Save
+# index
+index.heading=MailReader Options
+index.login=Log into MailReader
+index.login.title=MailReader - Login
+index.register=Register with MailReader
+index.title=MailReader
+index.tour=A Walking Tour of the MailReader Demonstration Application
+# login
+login.title=MailReader - Logon
+# register
+user.title.create=MailReader - Create Registration
+user.index.title=MailReader - Main Menu
+user.index.heading=Menu Options for
+user.index.register=Edit your registration profile
+user.index.logout=Log out of MailReader
+heading.subscriptions=Current Subscriptions
+heading.action=Action
+heading.create=Add
+heading.delete=Delete
+heading.update=Edit
+# subscribe
+subscription.title.create=MailReader - Create Subscription
+subscription.title.delete=MailReader - Delete Subscription
+# option
+option.imap=IMAP Protocol
+option.pop3=POP3 Protocol
+# prompts
+subscription.autoConnect=Auto Connect
+subscription.host=Mail Server
+subscription.password=Mail Password
+subscription.protocol=Server Type
+subscription.username=Mail Username
+
+# error (field)
+error.username.required=Please enter a Username
+error.fullName.required=Please enter a Full Name
+error.fromAddress.required=Please enter a From Address
+error.fromAddress.format=Please correct the email format for From Address
+error.host.required=Please enter a Mail Server host
+error.host.unique=That hostname is already defined
+error.replyToAddress.format=Please correct the email format for Reply To Address
+error.password.required=Please enter a Password
+error.password2.required=Please enter the password again as a confirmation
+error.password.match=Password and confirmation password must match
+error.type.invalid=Server Type must be 'imap' or 'pop3'
+error.type.required=Server Type is required
+# error (global)
+error.database.missing=User database is missing, cannot validate logon credentials
+error.username.unique=That username is already in use - please select another
+error.password.mismatch=Invalid username and/or password, please try again
+linkSubscription.io=I/O Error: {0}
+
+# error messages
+error.noSubscription=No Subscription bean in user session
+error.password.expired=Your password has expired for username {0}
+error.password.length=Please enter a password that is between 4 and 10 characters in length
+# 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)}
+
+# struts 1 errors settings
+errors.footer=</ul><hr>
+errors.header=<h3><font color="red">Validation Error</font></h3><p>You must correct the following error(s) before proceeding:</p><ul>
+errors.prefix=<li>
+errors.suffix=</li>
+errors.ioException=I/O exception rendering error messages: {0}
+
+# future use
+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}
+struts.messages.invalid.token=Cannot submit this form out of order
+expired.password=User Password has expired for {0}
+linkSubscription.noSubscription=No subscription under attribute {0}
+linkUser.io=I/O Error: {0}
+linkUser.noUser=No user under attribute {0}
+user.title.update=MailReader - Update Registration
+subscription.title.update=MailReader - Update Subscription
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ja.properties
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ja.properties?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ja.properties (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ja.properties Mon Nov 19 23:37:56 2007
@@ -0,0 +1,85 @@
+subscription.autoConnect=\u81ea\u52d5\u63a5\u7d9a
+button.cancel=\u30ad\u30e3\u30f3\u30bb\u30eb
+button.confirm=\u78ba\u8a8d
+button.reset=\u30ea\u30bb\u30c3\u30c8
+button.update=\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.title=\u30d1\u30b9\u30ef\u30fc\u30c9\u671f\u9650\u5207\u308c
+change.try=\u518D\u8A66\u884C
+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.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.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.replyToAddress.format=\u8FD4\u4FE1\u30A2\u30C9\u30EC\u30B9\u306E\u66F8\u5F0F\u304C\u6B63\u3057\u304F\u3042\u308A\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.byte=${getText(fieldName)} \u306fbyte\u578b\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.date=${getText(fieldName)} \u306f\u65e5\u4ed8\u3067\u306f\u3042\u308a\u307e\u305b\u3093\u3002
+errors.double=${getText(fieldName)} \u306fdouble\u578b\u3067\u306a\u3051\u308c\u3070\u306a\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
+errors.float=${getText(fieldName)} \u306ffloat\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.footer=</ul><hr>
+errors.header=<h3><font color="red">\u5165\u529b\u30c1\u30a7\u30c3\u30af\u30a8\u30e9\u30fc</font></h3><p>\u4ee5\u4e0b\u306e\u30a8\u30e9\u30fc\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044:</p><ul>
+errors.integer=${getText(fieldName)} \u306finteger\u578b\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.ioException=I/O\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3057\u305f: {0}
+errors.long=${getText(fieldName)} \u306flong\u578b\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.minlength=${getText(fieldName)} \u306f {1} \u6587\u5b57\u4ee5\u4e0a\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.prefix=<li>
+errors.range=${getText(fieldName)} \u306f {1} \u304b\u3089 {2} \u306e\u9593\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.required=${getText(fieldName)} \u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\u3002
+errors.short=${getText(fieldName)} \u306fshort\u578b\u3067\u306a\u3051\u308c\u3070\u306a\u308a\u307e\u305b\u3093\u3002
+errors.suffix=</li>
+expired.password=\u30E6\u30FC\u30B6 {0} \u306E\u30D1\u30B9\u30EF\u30FC\u30C9\u306E\u6709\u52B9\u671F\u9650\u304C\u904E\u304E\u307E\u3057\u305F
+user.fromAddress=From\u30a2\u30c9\u30ec\u30b9
+user.fullName=\u30d5\u30eb\u30cd\u30fc\u30e0
+heading.action=\u64cd\u4f5c
+subscriptions.heading=\u73fe\u5728\u306e\u8cfc\u8aad\u60c5\u5831
+index.register=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e6\u30fc\u30b6\u767b\u9332
+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
+subscription.Hostname=\u30e1\u30fc\u30eb\u30b5\u30fc\u30d0
+subscription.password=\u30e1\u30fc\u30eb\u30d1\u30b9\u30ef\u30fc\u30c9
+subscription.protocol=\u30b5\u30fc\u30d0\u30bf\u30a4\u30d7
+subscription.username=\u30e1\u30fc\u30eb\u30e6\u30fc\u30b6\u540d
+user.index.heading=\u30e1\u30a4\u30f3\u30e1\u30cb\u30e5\u30fc
+user.index.logout=MailReader \u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u306e\u30ed\u30b0\u30aa\u30d5
+user.index.register=\u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u306e\u7de8\u96c6
+user.index.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
+user.password=\u30d1\u30b9\u30ef\u30fc\u30c9
+user.password1=\u30d1\u30b9\u30ef\u30fc\u30c9
+user.password2=\u30d1\u30b9\u30ef\u30fc\u30c9(\u78ba\u8a8d\u7528)
+heading.delete=\u524a\u9664
+heading.create=\u65b0\u898f\u4f5c\u6210
+heading.update=\u7de8\u96c6
+user.title.create=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30e6\u30fc\u30b6\u767b\u9332
+user.title.update=MailReader\u30c7\u30e2\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3 - \u30d7\u30ed\u30d5\u30a1\u30a4\u30eb\u7de8\u96c6
+user.replyToAddress=\u8fd4\u4fe1\u30a2\u30c9\u30ec\u30b9
+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
+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.update=\u30e1\u30fc\u30eb\u8cfc\u8aad\u60c5\u5831\u306e\u7de8\u96c6
+user.username=\u30e6\u30fc\u30b6\u540d
+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.login.title=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
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ru.properties
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ru.properties?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ru.properties (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/package_ru.properties Mon Nov 19 23:37:56 2007
@@ -0,0 +1,84 @@
+subscription.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:
+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.update=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c
+change.message=Your password has expired. Please ask the system administrator to change it.
+change.title=Password Has Expired
+change.try=Try Again
+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.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.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.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.
+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.byte=${getText(fieldName)} must be an byte.
+errors.creditcard=${getText(fieldName)} is not a valid credit card number.
+errors.date=${getText(fieldName)} is not a date.
+errors.double=${getText(fieldName)} must be an double.
+errors.email=${getText(fieldName)} is an invalid e-mail address.
+errors.float=${getText(fieldName)} must be an float.
+errors.footer=</ul><hr>
+errors.header=<h3><font color="red">\u041e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0437\u0430\u043d\u0435\u0441\u0435\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445</font></h3><p>\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:</p><ul>
+errors.integer=${getText(fieldName)} must be an integer.
+errors.invalid=${getText(fieldName)} is invalid.
+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}
+errors.long=${getText(fieldName)} must be an long.
+errors.maxlength=${getText(fieldName)} cannot be greater than {2} characters.
+errors.minlength=${getText(fieldName)} cannot be less than {1} characters.
+errors.prefix=<li>
+errors.range=${getText(fieldName)} is not in the range {1} through {2}.
+errors.required=${getText(fieldName)} is required.
+errors.short=${getText(fieldName)} must be an short.
+errors.suffix=</li>
+expired.password=User Password has expired for {0}
+user.fromAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442:
+user.fullName=\u041f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f:
+heading.action=\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435
+subscriptions.heading=\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
+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.
+subscription.Hostname=\u041f\u043e\u0447\u0442\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440:
+subscription.password=\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:
+subscription.protocol=\u0422\u0438\u043f \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
+subscription.username=\u0418\u043c\u044f \u0434\u043b\u044f \u043f\u043e\u0447\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430:
+mainuser.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' - \u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u043c\u0435\u043d\u044e
+user.index.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
+user.index.register=\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0432\u043e\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438
+user.index.logout=\u0412\u044b\u0439\u0442\u0438
+option.imap=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b IMAP
+option.pop3=\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b POP3
+user.password=\u041f\u0430\u0440\u043e\u043b\u044c:
+user.password1=\u041f\u0430\u0440\u043e\u043b\u044c:
+user.password2=(\u041f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435) \u041f\u0430\u0440\u043e\u043b\u044c:
+heading.delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c
+heading.create=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c
+heading.update=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c
+user.title.create=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+user.title.update=\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
+replyToAddress=\u0410\u0434\u0440\u0435\u0441 \u041e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430:
+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.
+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.update=\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
+user.username=\u0418\u043c\u044f:
+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.registration=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+index.login.title=\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.registration=\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f
+index.register==\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'
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Create.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Create.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Create.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Create.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user;
+
+import org.apache.struts2.config.Result;
+import org.apache.struts2.config.Results;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+import com.opensymphony.xwork2.validator.annotations.EmailValidator;
+import com.opensymphony.xwork2.validator.annotations.ExpressionValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.Validation;
+import com.opensymphony.xwork2.validator.annotations.Validations;
+
+@Results( {
+ @Result(name = Index.CANCEL, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NONE }),
+ @Result(name = Index.SUCCESS, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.USER, Index.USER_USERNAME }) })
+@Validation()
+public class Create extends Index {
+
+ // FIXME: Can the email validations by applied to getUser?
+ @Validations(requiredStrings = {
+ @RequiredStringValidator(fieldName = "user.username", key = "error.username.required", message = ""),
+ @RequiredStringValidator(fieldName = "user.fullName", key = "error.fullName.required", message = ""),
+ @RequiredStringValidator(fieldName = "user.fromAddress", key = "error.fromAddress.required", message = ""),
+ @RequiredStringValidator(fieldName = "user.password1", key = "error.password.required", message = ""),
+ @RequiredStringValidator(fieldName = "user.password2", key = "error.password2.required", message = "") }, stringLengthFields = { @StringLengthFieldValidator(fieldName = "user.password1", key = "error.password.length", message = "", trim = true, minLength = "4", maxLength = "12") }, emails = {
+ @EmailValidator(fieldName = "user.fromAddress", key = Index.ERROR_FROM_ADDRESS_FORMAT, message = Index.NONE),
+ @EmailValidator(fieldName = "user.replyTo", key = Index.ERROR_REPLY_TO_ADDRESS_FORMAT, message = Index.NONE) })
+ @StringLengthFieldValidator(fieldName = "user.password1", key = "error.password.length", message = "", trim = true, minLength = "4", maxLength = "12")
+ @ExpressionValidator(key = "error.password.match", message = "", expression = "password1 eq password2")
+ public String execute() throws Exception {
+ if (!CREATE.equals(getInput()))
+ return INPUT;
+ create();
+ return (hasErrors()) ? INPUT : SUCCESS;
+ }
+
+ public String input() throws Exception {
+ setInput(CREATE);
+ return super.input();
+ }
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Index.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Index.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Index.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Index.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user;
+
+import entity.user.User;
+import entity.user.UserManager;
+import entity.user.UserManagerInterface;
+
+public class Index extends action.Index {
+
+ // ---- STATICS ----
+
+ static final String ERROR_FROM_ADDRESS_FORMAT = "error.fromAddress.format";
+
+ static final String ERROR_PASSWORD_MATCH = "error.password.match";
+
+ static final String ERROR_PASSWORD_LENGTH = "error.password.length";
+
+ static final String ERROR_REPLY_TO_ADDRESS_FORMAT = "error.replyToAddress.format";
+
+ static final String ERROR_CREDENTIALS_MISMATCH = "error.password.mismatch";
+
+ static final String ERROR_USERNAME_UNIQUE = "error.username.unique";
+
+ static final String PASSWORD_MISMATCH_FIELD = "password";
+
+ // ---- PROPERTIES ----
+
+ UserManagerInterface manager;
+
+ public String getLocation() {
+ return "/WEB-INF/results/user/";
+ }
+
+ private User user;
+
+ public User getUser() {
+ return user;
+ }
+
+ public void setUser(User value) {
+ user = value;
+ }
+
+ // ---- METHODS ----
+
+ protected void authenticate() throws Exception {
+ String username = getUser().getUsername();
+ String password = getUser().getPassword1();
+
+ User foundValue = manager.findByName(username);
+ if ((foundValue != null) && !foundValue.getPassword().equals(password)) {
+ foundValue = null;
+ }
+
+ boolean isFound = (foundValue != null);
+ if (isFound) {
+ setUser(foundValue);
+ login();
+ } else {
+ addFieldError(PASSWORD_MISMATCH_FIELD,
+ getText(ERROR_CREDENTIALS_MISMATCH));
+ }
+ }
+
+ protected void create() throws Exception {
+ String username = getUser().getUsername();
+ String password = getUser().getPassword1();
+
+ User foundValue = manager.findByName(username);
+ boolean isNameInUse = (foundValue != null);
+ if (isNameInUse) {
+ addActionError(getText(ERROR_USERNAME_UNIQUE));
+ } else {
+ User newValue = getUser();
+ newValue.setPassword(password);
+ // Let other details carryover
+ manager.create(newValue);
+ login();
+ }
+ }
+
+ protected void login() {
+ getProfile().put(USER, getUser());
+ }
+
+ protected void logout() {
+ getProfile().put(USER, null);
+ }
+
+ protected void update() throws Exception {
+ User result = getUser();
+ if (manager.hasId(result)) {
+ manager.update(result);
+ } else {
+ addActionError(getText(ERROR_CREDENTIALS_MISMATCH));
+ }
+ }
+
+ /**
+ * <p>
+ * Instantiate default instance.
+ * </p>
+ */
+ public Index() {
+ manager = new UserManager();
+ }
+
+ /**
+ * <p>
+ * Instantiate instance using specified <code>IUserManager</code>.
+ * </p>
+ *
+ * @param manager
+ * IUserManager instance
+ */
+ public Index(UserManagerInterface manager) {
+ this.manager = manager;
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Login.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Login.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Login.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Login.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,27 @@
+package action.user;
+
+import org.apache.struts2.config.Result;
+import org.apache.struts2.config.Results;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.Validation;
+import com.opensymphony.xwork2.validator.annotations.Validations;
+
+@Results( {
+ @Result(name = Index.CANCEL, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NONE }),
+ @Result(name = Index.SUCCESS, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.USER, Index.USER_USERNAME }) })
+@Validation()
+public class Login extends Index {
+
+ @Validations(requiredStrings = {
+ @RequiredStringValidator(fieldName = "user.username", key = "error.username.required", message = ""),
+ @RequiredStringValidator(fieldName = "user.password1", key = "error.password.required", message = "") })
+ public String execute() throws Exception {
+ authenticate();
+ return (hasErrors()) ? INPUT : SUCCESS;
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Logout.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Logout.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Logout.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Logout.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user;
+
+import org.apache.struts2.config.Result;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+
+@Result(name = Index.SUCCESS, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NONE })
+public class Logout extends Index {
+
+ public String execute() {
+ logout();
+ return SUCCESS;
+ }
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Update.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Update.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Update.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/Update.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user;
+
+import org.apache.struts2.config.Result;
+import org.apache.struts2.config.Results;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+
+import com.opensymphony.xwork2.validator.annotations.EmailValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.Validation;
+import com.opensymphony.xwork2.validator.annotations.Validations;
+
+@Results( {
+ @Result(name = Index.CANCEL, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.USER, Index.USER_USERNAME }),
+ @Result(name = Index.SUCCESS, value = Index.INDEX, type = ServletActionRedirectResult.class, params = {
+ Index.USER, Index.USER_USERNAME }) })
+@Validation()
+public class Update extends Index {
+
+ @Validations(requiredStrings = {
+ @RequiredStringValidator(fieldName = "user.username", key = "error.username.required", message = "", shortCircuit = true),
+ @RequiredStringValidator(fieldName = "user.fullName", key = "error.fullname.required", message = "", shortCircuit = true),
+ @RequiredStringValidator(fieldName = "user.fromAddress", key = "error.fromaddress.required", message = "", shortCircuit = true) }, emails = {
+ @EmailValidator(fieldName = "user.fromAddress", key = Index.ERROR_REPLY_TO_ADDRESS_FORMAT, message = Index.NONE),
+ @EmailValidator(fieldName = "user.replyTo", key = Index.ERROR_FROM_ADDRESS_FORMAT, message = Index.NONE) })
+ public String execute() throws Exception {
+
+ if (!UPDATE.equals(getInput()))
+ return INPUT;
+
+ String newPassword = getUser().getPassword1();
+ boolean changing = ((null != newPassword) && (newPassword.length() > 0));
+ if (changing) {
+ String confirmPassword = getUser().getPassword2();
+ boolean matches = ((null != confirmPassword) && (confirmPassword
+ .equals(newPassword)));
+ if (matches) {
+ getUser().setPassword(newPassword);
+ } else {
+ addActionError(getText(ERROR_PASSWORD_MATCH));
+ return INPUT;
+ }
+ }
+
+ update();
+ return (hasErrors()) ? INPUT : SUCCESS;
+ }
+
+ public String input() throws Exception {
+ setInput(UPDATE);
+ return super.input();
+ }
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Create.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Create.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Create.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Create.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user.subscription;
+
+import org.apache.struts2.config.Result;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+
+@Result(name = Index.CANCEL, value = Index.UPDATE_INPUT, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NS_USER, Index.USER, Index.USER_USERNAME })
+public class Create extends Index {
+
+ public String input() throws Exception {
+ setInput(CREATE);
+ return super.input();
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Delete.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Delete.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Delete.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Delete.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user.subscription;
+
+public class Delete extends Index {
+
+ public String input() throws Exception {
+ setInput(DELETE);
+ return manager.hasId(getSubscription()) ? super.input() : ERROR;
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Index.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Index.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Index.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Index.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user.subscription;
+
+import java.util.Map;
+
+import org.apache.struts2.config.Result;
+import org.apache.struts2.config.Results;
+import org.apache.struts2.dispatcher.ServletActionRedirectResult;
+
+import com.opensymphony.xwork2.Preparable;
+import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
+import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
+import com.opensymphony.xwork2.validator.annotations.Validation;
+import com.opensymphony.xwork2.validator.annotations.Validations;
+
+import entity.protocol.ProtocolManager;
+import entity.protocol.ProtocolManagerInterface;
+import entity.subscription.Subscription;
+import entity.subscription.SubscriptionManager;
+import entity.subscription.SubscriptionManagerInterface;
+import entity.user.User;
+
+@Results( {
+ @Result(name = Index.CANCEL, value = Index.UPDATE_INPUT, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NS_USER, Index.USER,
+ Index.SUBSCRIPTION_USER_USERNAME }),
+ @Result(name = Index.ERROR, value = Index.UPDATE_INPUT, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NS_USER, Index.USER,
+ Index.SUBSCRIPTION_USER_USERNAME }),
+ @Result(name = Index.SUCCESS, value = Index.UPDATE_INPUT, type = ServletActionRedirectResult.class, params = {
+ Index.NAMESPACE, Index.NS_USER, Index.USER,
+ Index.SUBSCRIPTION_USER_USERNAME }) })
+@Validation()
+public class Index extends action.user.Index implements Preparable {
+
+ protected static final String ERROR_HOST_UNIQUE = "error.host.unique";
+
+ static final String ERROR_CREDENTIALS_MISMATCH = "error.password.mismatch";
+
+ protected SubscriptionManagerInterface manager;
+ private ProtocolManagerInterface protocolManager;
+
+ private Map protocols;
+
+ public Map getProtocols() {
+ return protocols;
+ }
+
+ public void setProtocols(Map value) {
+ protocols = value;
+ }
+
+ private Subscription subscription;
+
+ public Subscription getSubscription() {
+ return subscription;
+ }
+
+ public void setSubscription(Subscription value) {
+ subscription = value;
+ }
+
+ private boolean validateHost(Subscription value) {
+ String name = value.getHost();
+ Subscription foundValue = manager.findByName(name);
+ boolean isNameInUse = (foundValue != null);
+ if (isNameInUse)
+ addFieldError(Subscription.HOST, getText(ERROR_HOST_UNIQUE));
+ return NotErrors();
+ }
+
+ private boolean validateUser(Subscription value) {
+ boolean needUser = (value.getUser() == null);
+ if (needUser) {
+ User defaultUser = getUser();
+ if (defaultUser == null) {
+ addFieldError(Subscription.HOST,
+ getText(ERROR_CREDENTIALS_MISMATCH));
+ } else {
+ value.setUser(getUser());
+ }
+ }
+ return NotErrors();
+ }
+
+ protected void create() throws Exception {
+ Subscription value = getSubscription();
+ boolean isValid = ((validateHost(value)) && (validateUser(value)));
+ if (isValid)
+ manager.create(value);
+ }
+
+ protected void delete() throws Exception {
+ Subscription value = getSubscription();
+ User user = value.getUser();
+ user.removeSubscription(value);
+ manager.delete(value);
+ }
+
+ protected void update() throws Exception {
+ Subscription result = getSubscription();
+ if (manager.hasId(result)) {
+ manager.update(result);
+ } else {
+ addActionError(getText(ERROR_CREDENTIALS_MISMATCH));
+ }
+ }
+
+ @Validations(requiredStrings = {
+ @RequiredStringValidator(fieldName = "subscription.host", key = "error.host.required", message = "", shortCircuit = true),
+ @RequiredStringValidator(fieldName = "subscription.username", key = "error.username.required", message = "", shortCircuit = true),
+ @RequiredStringValidator(fieldName = "subscription.password", key = "error.password.required", message = "", shortCircuit = true) })
+ @RequiredFieldValidator(fieldName = "subscription.protocol", key = "error.type.required", message = "", shortCircuit = true)
+ public String execute() throws Exception {
+
+ String input = getInput();
+
+ if (CREATE.equals(input))
+ create();
+
+ if (UPDATE.equals(input))
+ update();
+
+ if (DELETE.equals(input))
+ delete();
+
+ if (hasErrors())
+ return INPUT;
+
+ return SUCCESS;
+
+ }
+
+ public void prepare() {
+ setProtocols(protocolManager.findAllAsMap());
+ }
+
+ /**
+ * <p>
+ * Instantiate default instance.
+ * </p>
+ */
+ public Index() {
+ manager = new SubscriptionManager();
+ protocolManager = new ProtocolManager();
+ }
+
+ /**
+ * <p>
+ * Instantiate instance using specified <code>ISubscriptionManager</code>
+ * and <code>IProtocolManager</code> .
+ * </p>
+ *
+ * @param manager
+ * IUserManager instance
+ */
+ public Index(SubscriptionManagerInterface manager,
+ ProtocolManagerInterface protocolManager) {
+ this.manager = manager;
+ this.protocolManager = protocolManager;
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Update.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Update.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Update.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/action/user/subscription/Update.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 action.user.subscription;
+
+public class Update extends Index {
+
+ public String input() throws Exception {
+ setInput(UPDATE);
+ return manager.hasId(getSubscription()) ? super.input() : ERROR;
+ }
+
+}
Added: struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntityManagerHelper.java
URL: http://svn.apache.org/viewvc/struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntityManagerHelper.java?rev=596559&view=auto
==============================================================================
--- struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntityManagerHelper.java (added)
+++ struts/sandbox/trunk/jpa-mailreader/src/main/java/entity/EntityManagerHelper.java Mon Nov 19 23:37:56 2007
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 entity;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+/**
+ * <p>
+ * Provide access to JPA implementation using static methods.
+ * </p>
+ */
+public class EntityManagerHelper {
+
+ static final String PERSISTENCE_UNIT = "entity";
+
+ private static final EntityManagerFactory emf;
+ private static final ThreadLocal<EntityManager> threadLocal;
+ private static final Logger logger;
+
+ static {
+ emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT);
+ threadLocal = new ThreadLocal<EntityManager>();
+ logger = Logger.getLogger(PERSISTENCE_UNIT);
+ logger.setLevel(Level.ALL);
+ }
+
+ public static EntityManager getEntityManager() {
+ EntityManager manager = threadLocal.get();
+ if (manager == null || !manager.isOpen()) {
+ manager = emf.createEntityManager();
+ threadLocal.set(manager);
+ }
+ return manager;
+ }
+
+ public static void closeEntityManager() {
+ EntityManager em = threadLocal.get();
+ threadLocal.set(null);
+ if (em != null)
+ em.close();
+ }
+
+ public static void beginTransaction() {
+ getEntityManager().getTransaction().begin();
+ }
+
+ public static void commit() {
+ getEntityManager().getTransaction().commit();
+ }
+
+ public static void rollback() {
+ getEntityManager().getTransaction().rollback();
+ }
+
+ public static Query createQuery(String query) {
+ return getEntityManager().createQuery(query);
+ }
+
+ public static void log(String info, Level level, Throwable ex) {
+ logger.log(level, info, ex);
+ }
+
+ public static void log(String info, Throwable ex) {
+ logger.log(Level.INFO, info, ex);
+ }
+
+}